This is an automated email from the ASF dual-hosted git repository. juzhiyuan pushed a commit to branch feat-plugins in repository https://gitbox.apache.org/repos/asf/incubator-apisix-dashboard.git
commit 8523d74ae0791340ecffad27f139cfad3d9b21e7 Author: juzhiyuan <[email protected]> AuthorDate: Thu Jun 11 11:59:00 2020 +0800 feat: refactor plugin list --- src/components/PluginForm/data.ts | 129 ++++++++++++--------- src/components/PluginForm/index.ts | 2 - src/components/PluginForm/service.ts | 2 - src/components/PluginForm/typing.d.ts | 7 +- src/pages/Routes/Create.tsx | 30 ++++- .../Routes/components/CreateStep3/CreateStep3.tsx | 55 +++------ src/pages/Routes/constants.ts | 2 + src/pages/Routes/service.ts | 2 + src/pages/Routes/typing.d.ts | 2 + 9 files changed, 132 insertions(+), 99 deletions(-) diff --git a/src/components/PluginForm/data.ts b/src/components/PluginForm/data.ts index f4d6afa..44c74f5 100644 --- a/src/components/PluginForm/data.ts +++ b/src/components/PluginForm/data.ts @@ -1,83 +1,100 @@ -export const list: PluginForm.PluginProps[] = [ - { - name: 'basic-auth', +export const PLUGIN_MAPPER_SOURCE: { [name: string]: PluginForm.PluginMapperItem } = { + 'limit-req': { + category: '', }, - { - name: 'batch-requests', + 'limit-count': { + category: '', }, - { - name: 'cors', + 'limit-conn': { + category: '', }, - { - name: 'fault-injection', + 'key-auth': { + category: '', + hidden: true, }, - { - name: 'grpc-transcoding', + 'basic-auth': { + category: '', + hidden: true, }, - { - name: 'http-logger', + prometheus: { + category: '', }, - { - name: 'ip-restriction', + 'node-status': { + category: '', }, - { - name: 'jwt-auth', + 'jwt-auth': { + category: '', + hidden: true, }, - { - name: 'kafka-logger', + zipkin: { + category: '', }, - { - name: 'key-auth', + 'ip-restriction': { + category: '', }, - { - name: 'limit-conn', + 'grpc-transcode': { + category: '', + hidden: true, }, - { - name: 'limit-count', + 'serverless-pre-function': { + category: '', }, - { - name: 'limit-req', + 'serverless-post-function': { + category: '', }, - { - name: 'mqtt-proxy', + 'openid-connect': { + category: '', }, - { - name: 'oauth', + 'proxy-rewrite': { + category: '', + hidden: true, }, - { - name: 'prometheus', + redirect: { + category: '', + hidden: true, }, - { - name: 'proxy-cache', + 'response-rewrite': { + category: '', }, - { - name: 'proxy-mirror', + 'fault-injection': { + category: '', }, - { - name: 'proxy-rewrite', + 'udp-logger': { + category: '', }, - { - name: 'redirect', + 'wolf-rbac': { + category: '', + hidden: true, }, - { - name: 'response-rewrite', + 'proxy-cache': { + category: '', }, - { - name: 'serverless', + 'tcp-logger': { + category: '', }, - { - name: 'syslog', + 'proxy-mirror': { + category: '', }, - { - name: 'tcp-logger', + 'kafka-logger': { + category: '', }, - { - name: 'udp-logger', + cors: { + category: '', }, - { - name: 'wolf-rbac', + heartbeat: { + category: '', }, - { - name: 'zipkin', + // BUG: 下面几个接口未返回 + 'batch-requests': { + category: '', }, -]; + 'http-logger': { + category: '', + }, + 'mqtt-proxy': { + category: '', + }, + oauth: { + category: '', + }, +}; diff --git a/src/components/PluginForm/index.ts b/src/components/PluginForm/index.ts index 4872268..8770cd6 100644 --- a/src/components/PluginForm/index.ts +++ b/src/components/PluginForm/index.ts @@ -1,5 +1,3 @@ export { default } from './PluginForm'; -export { fetchList as fetchPluginList } from './service'; -export { list as pluginList } from './data'; export { default as PluginFormZhCN } from './locales/zh-CN'; export { default as PluginFormEnUS } from './locales/en-US'; diff --git a/src/components/PluginForm/service.ts b/src/components/PluginForm/service.ts index 447bd9a..a688e9c 100644 --- a/src/components/PluginForm/service.ts +++ b/src/components/PluginForm/service.ts @@ -1,7 +1,5 @@ import { request } from 'umi'; import { transformSchemaFromAPI } from './transformer'; -export const fetchList = () => request('/plugins/list'); - export const fetchPluginSchema = (name: string): Promise<PluginForm.PluginSchema> => request(`/schema/plugins/${name}`).then((data) => transformSchemaFromAPI(data, name)); diff --git a/src/components/PluginForm/typing.d.ts b/src/components/PluginForm/typing.d.ts index 0d1fb08..3c5f6dd 100644 --- a/src/components/PluginForm/typing.d.ts +++ b/src/components/PluginForm/typing.d.ts @@ -51,7 +51,12 @@ declare namespace PluginForm { }; } - interface PluginProps { + type PluginMapperItem = { + category: string; + hidden?: boolean; + }; + + interface PluginProps extends PluginMapperItem { name: string; } } diff --git a/src/pages/Routes/Create.tsx b/src/pages/Routes/Create.tsx index 02187d3..d27bcad 100644 --- a/src/pages/Routes/Create.tsx +++ b/src/pages/Routes/Create.tsx @@ -2,7 +2,8 @@ import React, { useState, useEffect } from 'react'; import { Card, Steps, Form } from 'antd'; import { PageHeaderWrapper } from '@ant-design/pro-layout'; -import { createRoute, fetchRoute, updateRoute } from './service'; +import { PLUGIN_MAPPER_SOURCE } from '@/components/PluginForm/data'; +import { createRoute, fetchRoute, updateRoute, fetchPluginList } from './service'; import Step1 from './components/Step1'; import Step2 from './components/Step2'; import CreateStep3 from './components/CreateStep3'; @@ -30,7 +31,7 @@ const Create: React.FC = (props) => { const [form1] = Form.useForm(); const [form2] = Form.useForm(); - const [step, setStep] = useState(0); + const [step, setStep] = useState(2); const [stepHeader, setStepHeader] = useState(STEP_HEADER_4); const routeData = { @@ -55,6 +56,31 @@ const Create: React.FC = (props) => { if ((props as any).route.name === 'edit') { initRoute((props as any).match.params.rid); } + + const PLUGIN_BLOCK_LIST = Object.entries(PLUGIN_MAPPER_SOURCE) + .filter(([, value]) => value.hidden) + .flat() + .filter((item) => typeof item === 'string'); + + fetchPluginList().then((data: string[]) => { + const names = data.filter((name) => !PLUGIN_BLOCK_LIST.includes(name)); + let enabledList: PluginForm.PluginProps[] = names.map((name) => ({ + name, + ...PLUGIN_MAPPER_SOURCE[name], + })); + let disabledList: PluginForm.PluginProps[] = []; + // TODO: 国际化 + const enabledPluginNames = Object.keys(step3Data.plugins); + if (enabledPluginNames.length) { + disabledList = enabledList.filter((item) => !enabledPluginNames.includes(item.name)); + enabledList = enabledList.filter((item) => enabledPluginNames.includes(item.name)); + } + setStep3Data({ + ...step3Data, + _disabledPluginList: disabledList, + _enabledPluginList: enabledList, + }); + }); }, []); useEffect(() => { diff --git a/src/pages/Routes/components/CreateStep3/CreateStep3.tsx b/src/pages/Routes/components/CreateStep3/CreateStep3.tsx index 8d20af4..59e08c2 100644 --- a/src/pages/Routes/components/CreateStep3/CreateStep3.tsx +++ b/src/pages/Routes/components/CreateStep3/CreateStep3.tsx @@ -1,8 +1,8 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { SettingOutlined, LinkOutlined } from '@ant-design/icons'; import { omit, merge } from 'lodash'; -import { pluginList } from '@/components/PluginForm'; +import { PLUGIN_MAPPER_SOURCE } from '@/components/PluginForm/data'; import PanelSection from '../PanelSection'; import PluginDrawer from './PluginDrawer'; import PluginCard from './PluginCard'; @@ -17,38 +17,13 @@ const sectionStyle = { }; const CreateStep3: React.FC<Props> = ({ data, disabled, onChange }) => { - // NOTE: Plugin in blacklist WILL NOT be shown on Step3. - const pluginBlackList = [ - 'basic-auth', - 'batch-requests', - 'grpc-transcoding', - 'http-logger', - 'jwt-auth', - 'key-auth', - 'mqtt-proxy', - 'oauth', - 'redirect', - 'wolf-rbac', - // BUG: - 'proxy-rewrite', - ]; - - const list = pluginList.filter(({ name }) => !pluginBlackList.includes(name)); - const [activeList, setActiveList] = useState<PluginForm.PluginProps[]>([]); - const [inactiveList, setInactiveList] = useState<PluginForm.PluginProps[]>([]); - - 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>(); + const { _disabledPluginList = [], _enabledPluginList = [] } = data.step3Data; return ( <> <PanelSection title="已启用" style={sectionStyle}> - {activeList.map(({ name }) => ( + {_enabledPluginList.map(({ name }) => ( <PluginCard name={name} actions={[ @@ -67,7 +42,7 @@ const CreateStep3: React.FC<Props> = ({ data, disabled, onChange }) => { </PanelSection> {!disabled && ( <PanelSection title="未启用" style={sectionStyle}> - {inactiveList.map(({ name }) => ( + {_disabledPluginList.map(({ name }) => ( <PluginCard name={name} actions={[ @@ -89,15 +64,23 @@ const CreateStep3: React.FC<Props> = ({ data, disabled, onChange }) => { name={currentPlugin} disabled={disabled} initialData={currentPlugin ? data.step3Data.plugins[currentPlugin] : {}} - active={Boolean(activeList.find((item) => item.name === currentPlugin))} + active={Boolean(_enabledPluginList.find((item) => item.name === currentPlugin))} onActive={(name: string) => { - setInactiveList(inactiveList.filter((item) => item.name !== name)); - setActiveList(activeList.concat({ name })); + onChange({ + ...data.step3Data, + _disabledPluginList: _disabledPluginList.filter((item) => item.name !== name), + _enabledPluginList: _enabledPluginList.concat({ name, ...PLUGIN_MAPPER_SOURCE[name] }), + }); }} onInactive={(name: string) => { - setActiveList(activeList.filter((item) => item.name !== name)); - setInactiveList(inactiveList.concat({ name })); - onChange(omit({ ...data.step3Data }, `plugins.${currentPlugin}`)); + onChange({ + ...omit({ ...data.step3Data }, `plugins.${currentPlugin}`), + _disabledPluginList: _disabledPluginList.concat({ + name, + ...PLUGIN_MAPPER_SOURCE[name], + }), + _enabledPluginList: _enabledPluginList.filter((item) => item.name !== name), + }); setCurrentPlugin(undefined); }} onClose={() => setCurrentPlugin(undefined)} diff --git a/src/pages/Routes/constants.ts b/src/pages/Routes/constants.ts index c0ef624..5bcb489 100644 --- a/src/pages/Routes/constants.ts +++ b/src/pages/Routes/constants.ts @@ -52,6 +52,8 @@ export const DEFAULT_STEP_2_DATA: RouteModule.Step2Data = { export const DEFAULT_STEP_3_DATA: RouteModule.Step3Data = { plugins: {}, + _enabledPluginList: [], + _disabledPluginList: [], }; export const STEP_HEADER_2 = ['定义 API 请求', '预览']; diff --git a/src/pages/Routes/service.ts b/src/pages/Routes/service.ts index 9300030..9049d62 100644 --- a/src/pages/Routes/service.ts +++ b/src/pages/Routes/service.ts @@ -21,3 +21,5 @@ export const fetchRouteList = (wid = 0) => request(`/workspaces/${wid}/routes?pa export const removeRoute = (rid: number, wid = 0) => request(`/workspaces/${wid}/routes/${rid}`, { method: 'DELETE' }); + +export const fetchPluginList = () => request('/plugins'); diff --git a/src/pages/Routes/typing.d.ts b/src/pages/Routes/typing.d.ts index 6b42531..aad0372 100644 --- a/src/pages/Routes/typing.d.ts +++ b/src/pages/Routes/typing.d.ts @@ -38,6 +38,8 @@ declare namespace RouteModule { plugins: { [name: string]: any; }; + _enabledPluginList: PluginForm.PluginProps[]; + _disabledPluginList: PluginForm.PluginProps[]; }; interface Data {
