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/09/06 11:42:03 UTC

[apisix-dashboard] branch master updated: feat: use reduplicate library (#445)

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

juzhiyuan 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 24c6460  feat: use reduplicate library (#445)
24c6460 is described below

commit 24c6460c2402e1d8439a5f014ec4a39ee6e0b1b6
Author: 琚致远 <ju...@apache.org>
AuthorDate: Sun Sep 6 19:41:56 2020 +0800

    feat: use reduplicate library (#445)
    
    * feat: use api7-dashboard/plugin
    
    * feat: use @api7-dashboard/ui
    
    * feat: remove unused locales
    
    * feat: update version
    
    * feat: update plugin & chart
---
 I18N_USER_GUIDE.md                                 |  12 --
 package.json                                       |   6 +-
 src/components/PanelSection/index.tsx              |  32 ----
 src/components/PluginForm/PluginForm.tsx           | 208 ---------------------
 src/components/PluginForm/README.md                |  27 ---
 src/components/PluginForm/data.ts                  | 116 ------------
 src/components/PluginForm/index.ts                 |  19 --
 src/components/PluginForm/locales/en-US.ts         | 178 ------------------
 src/components/PluginForm/locales/zh-CN.ts         | 178 ------------------
 src/components/PluginForm/service.ts               |  21 ---
 src/components/PluginForm/transformer.ts           | 106 -----------
 src/components/PluginForm/typing.d.ts              |  80 --------
 src/components/PluginModal/index.tsx               |  47 -----
 src/components/PluginPage/PluginCard.tsx           |  42 -----
 src/components/PluginPage/PluginDrawer.tsx         | 119 ------------
 src/components/PluginPage/PluginPage.tsx           | 143 --------------
 src/components/PluginPage/data.ts                  | 113 -----------
 src/components/PluginPage/index.ts                 |  22 ---
 src/components/PluginPage/locales/en-US.ts         | 188 -------------------
 src/components/PluginPage/locales/zh-CN.ts         | 188 -------------------
 src/components/PluginPage/service.ts               |  45 -----
 src/components/PluginPage/typing.d.ts              |  30 ---
 src/locales/en-US.ts                               |   2 -
 src/locales/zh-CN.ts                               |   2 -
 src/pages/Consumer/Create.tsx                      |   5 +-
 src/pages/Consumer/components/Preview.tsx          |   5 +-
 .../Route/components/CreateStep4/CreateStep4.tsx   |   4 +-
 .../Route/components/Step1/MatchingRulesView.tsx   |   3 +-
 src/pages/Route/components/Step1/MetaView.tsx      |  13 +-
 .../Route/components/Step1/RequestConfigView.tsx   |   3 +-
 .../components/Step2/HttpHeaderRewriteView.tsx     |   3 +-
 .../Route/components/Step2/RequestRewriteView.tsx  |   2 +-
 yarn.lock                                          |  16 +-
 33 files changed, 29 insertions(+), 1949 deletions(-)

diff --git a/I18N_USER_GUIDE.md b/I18N_USER_GUIDE.md
index 0ebd44f..9e1b991 100644
--- a/I18N_USER_GUIDE.md
+++ b/I18N_USER_GUIDE.md
@@ -90,18 +90,6 @@ we have already defined many global keys, before you do i18n, you can refer to [
 'page.route.button.returnList': '返回路由列表',
 ```
 
-- **PanelSection**
-
-| element      | props | locale subKey      |
-| ------------ | ----- | ------------------ |
-| PanelSection | title | panelSection.title |
-
-**Example:**
-
-```js
-'page.route.panelSection.title.nameDescription': '名称及其描述',
-```
-
 - **Steps**
 
 | element    | props | locale subKey   |
diff --git a/package.json b/package.json
index d4db220..87b7116 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "apisix-dashboard",
-  "version": "1.1.1",
+  "version": "1.5.2",
   "private": true,
   "description": "Dashboard for Apache APISIX",
   "scripts": {
@@ -54,8 +54,8 @@
     "@ant-design/icons": "^4.0.0",
     "@ant-design/pro-layout": "^6.0.0",
     "@ant-design/pro-table": "2.6.3",
-    "@api7-dashboard/plugin": "^1.0.2",
-    "@api7-dashboard/pluginchart": "^1.0.8",
+    "@api7-dashboard/plugin": "^1.0.3",
+    "@api7-dashboard/pluginchart": "^1.0.9",
     "@api7-dashboard/ui": "^1.0.0",
     "@rjsf/antd": "2.2.0",
     "@rjsf/core": "2.2.0",
diff --git a/src/components/PanelSection/index.tsx b/src/components/PanelSection/index.tsx
deleted file mode 100644
index 3fa5982..0000000
--- a/src/components/PanelSection/index.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, { CSSProperties } from 'react';
-import { Divider } from 'antd';
-
-const PanelSection: React.FC<{
-  title: string;
-  style?: CSSProperties;
-}> = ({ title, style, children }) => {
-  return (
-    <>
-      <Divider orientation="left">{title}</Divider>
-      <div style={style}>{children}</div>
-    </>
-  );
-};
-
-export default PanelSection;
diff --git a/src/components/PluginForm/PluginForm.tsx b/src/components/PluginForm/PluginForm.tsx
deleted file mode 100644
index 184e147..0000000
--- a/src/components/PluginForm/PluginForm.tsx
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, { useState, useEffect } from 'react';
-import { Form, Input, Switch, Select, InputNumber, Button } from 'antd';
-import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons';
-import { useIntl } from 'umi';
-
-import { fetchPluginSchema } from './service';
-import { transformPropertyToRules } from './transformer';
-
-const formLayout = {
-  labelCol: { span: 10 },
-  wrapperCol: { span: 14 },
-};
-
-interface RenderComponentProps {
-  placeholder?: string;
-  disabled?: boolean;
-}
-
-const renderComponentByProperty = (
-  propertyValue: PluginForm.PluginProperty,
-  restProps?: RenderComponentProps,
-) => {
-  const { type, minimum, maximum } = propertyValue;
-
-  if (type === 'string') {
-    if (propertyValue.enum) {
-      return (
-        <Select disabled={restProps?.disabled}>
-          {propertyValue.enum.map((enumValue) => (
-            <Select.Option value={enumValue} key={enumValue}>
-              {enumValue}
-            </Select.Option>
-          ))}
-        </Select>
-      );
-    }
-    return <Input {...restProps} />;
-  }
-
-  if (type === 'boolean') {
-    return <Switch {...restProps} />;
-  }
-
-  if (type === 'number' || type === 'integer') {
-    return (
-      <InputNumber
-        min={minimum ?? Number.MIN_SAFE_INTEGER}
-        max={maximum ?? Number.MAX_SAFE_INTEGER}
-        {...restProps}
-      />
-    );
-  }
-
-  return <Input {...restProps} />;
-};
-
-interface ArrayComponentProps {
-  disabled?: boolean;
-  schema: PluginForm.PluginSchema;
-  propertyName: string;
-  propertyValue: PluginForm.PluginProperty;
-}
-
-const ArrayComponent: React.FC<ArrayComponentProps> = ({
-  propertyName,
-  propertyValue,
-  schema,
-  disabled,
-  children,
-}) => {
-  const { formatMessage } = useIntl();
-  return (
-    <Form.List key={propertyName} name={propertyName}>
-      {(fields, { add, remove }) => (
-        <>
-          {fields.map((field, index) => (
-            <Form.Item
-              key={field.key}
-              rules={transformPropertyToRules(schema!, propertyName, propertyValue)}
-              label={`${propertyName}-${index + 1}`}
-            >
-              {children}
-              {fields.length > 1 ? (
-                <MinusCircleOutlined onClick={() => remove(field.name)} />
-              ) : (
-                <React.Fragment />
-              )}
-            </Form.Item>
-          ))}
-          {/* BUG: There should also care about minItems */}
-          {fields.length < (propertyValue.maxItems ?? Number.MAX_SAFE_INTEGER) ? (
-            <Form.Item label={propertyName}>
-              <Button type="dashed" onClick={add} disabled={disabled}>
-                <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
-              </Button>
-            </Form.Item>
-          ) : null}
-        </>
-      )}
-    </Form.List>
-  );
-};
-
-const PluginForm: React.FC<PluginForm.Props> = ({
-  name,
-  form,
-  disabled,
-  initialData = {},
-  onFinish,
-}) => {
-  const { formatMessage } = useIntl();
-  const [schema, setSchema] = useState<PluginForm.PluginSchema>();
-
-  useEffect(() => {
-    if (name) {
-      setSchema(undefined);
-      fetchPluginSchema(name).then((data) => {
-        setSchema(data);
-
-        const propertyDefaultData = {};
-        Object.entries(data.properties || {}).forEach(([propertyName, propertyValue]) => {
-          if (propertyValue.hasOwnProperty('default')) {
-            propertyDefaultData[propertyName] = propertyValue.default;
-          }
-        });
-        form.setFieldsValue(propertyDefaultData);
-
-        requestAnimationFrame(() => {
-          form.setFieldsValue(initialData);
-        });
-      });
-    }
-  }, [name]);
-
-  return (
-    <Form {...formLayout} form={form} onFinish={onFinish} labelAlign="left">
-      {Object.entries(schema?.properties || {}).map(([propertyName, propertyValue]) => {
-        // eslint-disable-next-line arrow-body-style
-        if (propertyValue.type === 'array') {
-          return (
-            <ArrayComponent
-              key={propertyName}
-              disabled={disabled}
-              schema={schema!}
-              propertyName={propertyName}
-              propertyValue={propertyValue}
-            >
-              {renderComponentByProperty({ type: 'string' })}
-            </ArrayComponent>
-          );
-        }
-
-        if (propertyValue.type === 'object') {
-          return (
-            <ArrayComponent
-              key={propertyName}
-              disabled={disabled}
-              schema={schema!}
-              propertyName={propertyName}
-              propertyValue={propertyValue}
-            >
-              {/* TODO: there should not be fixed value, and it should receive custom key */}
-              {renderComponentByProperty({ type: 'string' }, { placeholder: 'Header' })}
-              {renderComponentByProperty({ type: 'string' }, { placeholder: 'Value' })}
-            </ArrayComponent>
-          );
-        }
-
-        return (
-          <Form.Item
-            label={formatMessage({
-              id: `PluginForm.plugin.${name}.property.${propertyName}`,
-              defaultMessage: propertyName,
-            })}
-            extra={formatMessage({
-              id: `PluginForm.plugin.${name}.property.${propertyName}.extra`,
-              defaultMessage: '',
-            })}
-            name={propertyName}
-            key={propertyName}
-            rules={transformPropertyToRules(schema!, propertyName, propertyValue)}
-            valuePropName={propertyValue.type === 'boolean' ? 'checked' : 'value'}
-          >
-            {renderComponentByProperty(propertyValue, { disabled })}
-          </Form.Item>
-        );
-      })}
-    </Form>
-  );
-};
-
-export default PluginForm;
diff --git a/src/components/PluginForm/README.md b/src/components/PluginForm/README.md
deleted file mode 100644
index 12a6f2d..0000000
--- a/src/components/PluginForm/README.md
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
--->
-# PluginForm
-
-> The PluginForm component aims to build UI according to the plugin schema.
-
-## Usage
-
-1. Modify `list` variable in `data.ts` file.
-2. Modify filds under `/locales` folder to have a good translation.
-3. Import files under `/locales` folder to `/src/locales` to be localization.
diff --git a/src/components/PluginForm/data.ts b/src/components/PluginForm/data.ts
deleted file mode 100644
index b7c3259..0000000
--- a/src/components/PluginForm/data.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export const PLUGIN_MAPPER_SOURCE: { [name: string]: PluginForm.PluginMapperItem } = {
-  'limit-req': {
-    category: 'Limit',
-  },
-  'limit-count': {
-    category: 'Limit',
-  },
-  'limit-conn': {
-    category: 'Limit',
-  },
-  'key-auth': {
-    category: 'Security',
-    hidden: true,
-  },
-  'basic-auth': {
-    category: 'Security',
-    hidden: true,
-  },
-  prometheus: {
-    category: 'Metric',
-  },
-  'node-status': {
-    category: 'Other',
-  },
-  'jwt-auth': {
-    category: 'Security',
-    hidden: true,
-  },
-  zipkin: {
-    category: 'Metric',
-  },
-  'ip-restriction': {
-    category: 'Security',
-  },
-  'grpc-transcode': {
-    category: 'Other',
-    hidden: true,
-  },
-  'serverless-pre-function': {
-    category: 'Other',
-  },
-  'serverless-post-function': {
-    category: 'Other',
-  },
-  'openid-connect': {
-    category: 'Security',
-  },
-  'proxy-rewrite': {
-    category: 'Other',
-    hidden: true,
-  },
-  redirect: {
-    category: 'Other',
-    hidden: true,
-  },
-  'response-rewrite': {
-    category: 'Other',
-  },
-  'fault-injection': {
-    category: 'Security',
-  },
-  'udp-logger': {
-    category: 'Log',
-  },
-  'wolf-rbac': {
-    category: 'Other',
-    hidden: true,
-  },
-  'proxy-cache': {
-    category: 'Other',
-  },
-  'tcp-logger': {
-    category: 'Log',
-  },
-  'proxy-mirror': {
-    category: 'Other',
-  },
-  'kafka-logger': {
-    category: 'Log',
-  },
-  cors: {
-    category: 'Security',
-  },
-  heartbeat: {
-    category: 'Other',
-    hidden: true,
-  },
-  'batch-requests': {
-    category: 'Other',
-  },
-  'http-logger': {
-    category: 'Log',
-  },
-  'mqtt-proxy': {
-    category: 'Other',
-  },
-  oauth: {
-    category: 'Security',
-  },
-};
diff --git a/src/components/PluginForm/index.ts b/src/components/PluginForm/index.ts
deleted file mode 100644
index ff05061..0000000
--- a/src/components/PluginForm/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export { default } from './PluginForm';
-export { default as PluginFormZhCN } from './locales/zh-CN';
-export { default as PluginFormEnUS } from './locales/en-US';
diff --git a/src/components/PluginForm/locales/en-US.ts b/src/components/PluginForm/locales/en-US.ts
deleted file mode 100644
index 3efc205..0000000
--- a/src/components/PluginForm/locales/en-US.ts
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* eslint-disable no-template-curly-in-string */
-export default {
-  'PluginForm.plugin.limit-conn.desc': '限制并发连接数',
-  'PluginForm.plugin.limit-conn.property.conn': 'conn',
-  'PluginForm.plugin.limit-conn.property.conn.extra': '最大并发连接数',
-  'PluginForm.plugin.limit-conn.property.burst': 'burst',
-  'PluginForm.plugin.limit-conn.property.burst.extra':
-    '并发连接数超过 conn,但是低于 conn + burst 时,请求将被延迟处理',
-  'PluginForm.plugin.limit-conn.property.default_conn_delay': '延迟时间',
-  'PluginForm.plugin.limit-conn.property.default_conn_delay.extra':
-    '被延迟处理的请求,需要等待多少秒',
-  'PluginForm.plugin.limit-conn.property.key': 'key',
-  'PluginForm.plugin.limit-conn.property.key.extra': '用来做限制的依据',
-  'PluginForm.plugin.limit-conn.property.rejected_code': '拒绝状态码',
-  'PluginForm.plugin.limit-conn.property.rejected_code.extra':
-    '当并发连接数超过 conn + burst 的限制时,返回给终端的 HTTP 状态码',
-
-  'PluginForm.plugin.limit-count.desc': '在指定的时间范围内,限制总的请求次数',
-  'PluginForm.plugin.limit-count.property.count': '总请求次数',
-  'PluginForm.plugin.limit-count.property.count.extra': '指定时间窗口内的请求数量阈值',
-  'PluginForm.plugin.limit-count.property.time_window': '时间窗口',
-  'PluginForm.plugin.limit-count.property.time_window.extra':
-    '时间窗口的大小(以秒为单位),超过这个时间,总请求次数就会重置',
-  'PluginForm.plugin.limit-count.property.key': 'key',
-  'PluginForm.plugin.limit-count.property.key.extra': '用来做请求计数的依据',
-  'PluginForm.plugin.limit-count.property.rejected_code': '拒绝状态码',
-  'PluginForm.plugin.limit-count.property.rejected_code.extra':
-    '当请求超过阈值时,返回给终端的 HTTP 状态码',
-  'PluginForm.plugin.limit-count.property.policy': '策略',
-  'PluginForm.plugin.limit-count.property.redis_host': '地址',
-  'PluginForm.plugin.limit-count.property.redis_host.extra': '用于集群限流的 Redis 节点地址',
-  'PluginForm.plugin.limit-count.property.redis_port': '端口',
-  'PluginForm.plugin.limit-count.property.redis_password': '密码',
-  'PluginForm.plugin.limit-count.property.redis_timeout': '超时时间(毫秒)',
-
-  'PluginForm.plugin.limit-req.desc': '限制请求速度的插件,基于漏桶算法',
-  'PluginForm.plugin.limit-req.property.rate': 'rate',
-  'PluginForm.plugin.limit-req.property.rate.extra': '每秒请求速率',
-  'PluginForm.plugin.limit-req.property.burst': 'burst',
-  'PluginForm.plugin.limit-req.property.burst.extra':
-    '每秒请求速率超过 rate,但是低于 rate + burst 时,请求将被延迟处理',
-  'PluginForm.plugin.limit-req.property.key': 'key',
-  'PluginForm.plugin.limit-req.property.key.extra': '用来做请求计数的依据',
-  'PluginForm.plugin.limit-req.property.rejected_code': '拒绝状态码',
-  'PluginForm.plugin.limit-req.property.rejected_code.extra':
-    '速率超过 rate + burst 的限制时,返回给终端的 HTTP 状态码',
-
-  'PluginForm.plugin.cors.desc': 'CORS 插件可以为服务端启用 CORS 的返回头',
-  'PluginForm.plugin.cors.property.allow_origins': '允许跨域访问的 Origin',
-  'PluginForm.plugin.cors.property.allow_origins.extra': '比如 https://somehost.com:8081',
-  'PluginForm.plugin.cors.property.allow_methods': '允许跨域访问的 Method',
-
-  'PluginForm.plugin.fault-injection.desc': '故障注入插件,用来模拟各种后端故障和高延迟',
-  'PluginForm.plugin.fault-injection.property.http_status': 'HTTP 状态码',
-  'PluginForm.plugin.fault-injection.property.body': '响应体',
-  'PluginForm.plugin.fault-injection.property.duration': '延迟时间(秒)',
-
-  'PluginForm.plugin.http-logger.desc': 'http-logger 可以将日志数据请求推送到 HTTP/HTTPS 服务器',
-  'PluginForm.plugin.http-logger.property.uri': '日志服务器地址',
-  'PluginForm.plugin.http-logger.property.uri.extra': '比如 127.0.0.1:80/postendpoint?param=1',
-
-  'PluginForm.plugin.ip-restriction.desc':
-    'ip-restriction 可以把一批 IP 地址列入白名单或黑名单(二选一),时间复杂度是O(1),并支持用 CIDR 来表示 IP 范围',
-  'PluginForm.plugin.ip-restriction.property.whitelist': '白名单',
-  'PluginForm.plugin.ip-restriction.property.blacklist': '黑名单',
-
-  'PluginForm.plugin.kafka-logger.desc': '把接口请求日志以 JSON 的形式推送给外部 Kafka 集群',
-  'PluginForm.plugin.kafka-logger.property.broker_list': 'broker',
-  'PluginForm.plugin.kafka-logger.property.kafka_topic': 'topic',
-
-  'PluginForm.plugin.prometheus.desc': '提供符合 prometheus 数据格式的 metrics 数据',
-
-  'PluginForm.plugin.proxy-cache.desc': '代理缓存插件,缓存后端服务的响应数据',
-  'PluginForm.plugin.proxy-cache.property.cache_zone': '缓存区域名',
-  'PluginForm.plugin.proxy-cache.property.cache_zone.extra':
-    ' 本地目录为 /tmp/${区域名},修改默认区域名必须同时修改 config.yaml',
-  'PluginForm.plugin.proxy-cache.property.cache_key': '缓存 key',
-  'PluginForm.plugin.proxy-cache.property.cache_key.extra':
-    '可以使用 Nginx 变量,例如:$host, $uri',
-  'PluginForm.plugin.proxy-cache.property.cache_bypass': '跳过缓存检索',
-  'PluginForm.plugin.proxy-cache.property.cache_bypass.extra':
-    '这里可以使用 Nginx 变量,当此参数的值不为空或非0时将会跳过缓存的检索',
-  'PluginForm.plugin.proxy-cache.property.cache_method': '缓存 Method',
-  'PluginForm.plugin.proxy-cache.property.cache_http_status': '缓存响应状态码',
-  'PluginForm.plugin.proxy-cache.property.hide_cache_headers': '隐藏缓存头',
-  'PluginForm.plugin.proxy-cache.property.hide_cache_headers.extra':
-    '是否将 Expires 和 Cache-Control 响应头返回给客户端',
-  'PluginForm.plugin.proxy-cache.property.no_cache': '不缓存的数据',
-  'PluginForm.plugin.proxy-cache.property.no_cache.extra':
-    '这里可以使用 Nginx 变量, 当此参数的值不为空或非0时将不会缓存数据',
-
-  'PluginForm.plugin.proxy-mirror.desc': 'proxy mirror 代理镜像插件,提供了镜像客户端请求的能力',
-  'PluginForm.plugin.proxy-mirror.property.host': '镜像服务地址',
-  'PluginForm.plugin.proxy-mirror.property.host.extra':
-    '例如:http://127.0.0.1:9797。地址中需要包含 http 或 https,不能包含 URI 部分',
-
-  'PluginForm.plugin.response-rewrite.desc': '该插件支持修改上游服务返回的 body 和 header 信息',
-  'PluginForm.plugin.response-rewrite.property.status_code': '状态码',
-  'PluginForm.plugin.response-rewrite.property.body': '响应体',
-  'PluginForm.plugin.response-rewrite.property.body_base64': '响应体是否需要 base64 解码',
-  'PluginForm.plugin.response-rewrite.property.headers': 'HTTP 头',
-
-  'PluginForm.plugin.syslog.desc': '对接 syslog 日志服务器',
-  'PluginForm.plugin.syslog.property.host': '日志服务器地址',
-  'PluginForm.plugin.syslog.property.port': '日志服务器端口',
-  'PluginForm.plugin.syslog.property.timeout': '超时时间',
-  'PluginForm.plugin.syslog.property.tls': '开启 SSL',
-  'PluginForm.plugin.syslog.property.flush_limit': '缓存区大小',
-  'PluginForm.plugin.syslog.property.sock_type': '协议类型',
-  'PluginForm.plugin.syslog.property.max_retry_times': '重试次数',
-  'PluginForm.plugin.syslog.property.retry_interval': '重试间隔时间(毫秒)',
-  'PluginForm.plugin.syslog.property.pool_size': '连接池大小',
-
-  'PluginForm.plugin.tcp-logger.desc': '对接 TCP 日志服务器',
-  'PluginForm.plugin.tcp-logger.property.host': '日志服务器地址',
-  'PluginForm.plugin.tcp-logger.property.port': '日志服务器地址',
-  'PluginForm.plugin.tcp-logger.property.timeout': '超时时间',
-  'PluginForm.plugin.tcp-logger.property.tls': '开启 SSL',
-  'PluginForm.plugin.tcp-logger.property.tls_options': 'TLS 选型',
-
-  'PluginForm.plugin.udp-logger.desc': '对接 UDP 日志服务器',
-  'PluginForm.plugin.udp-logger.property.host': '日志服务器地址',
-  'PluginForm.plugin.udp-logger.property.port': '日志服务器地址',
-  'PluginForm.plugin.udp-logger.property.timeout': '超时时间',
-
-  'PluginForm.plugin.zipkin.desc': '对接 zipkin',
-  'PluginForm.plugin.zipkin.property.endpoint': 'endpoint',
-  'PluginForm.plugin.zipkin.property.endpoint.extra': '例如 http://127.0.0.1:9411/api/v2/spans',
-  'PluginForm.plugin.zipkin.property.sample_ratio': '采样率',
-  'PluginForm.plugin.zipkin.property.service_name': '服务名',
-  'PluginForm.plugin.zipkin.property.server_addr': '网关实例 IP',
-  'PluginForm.plugin.zipkin.property.server_addr.extra': '默认值是 Nginx 内置变量 server_addr',
-
-  'PluginForm.plugin.skywalking.desc': '对接 Apache Skywalking',
-  'PluginForm.plugin.skywalking.property.endpoint': 'endpoint',
-  'PluginForm.plugin.skywalking.property.endpoint.extra': '例如 http://127.0.0.1:12800',
-  'PluginForm.plugin.skywalking.property.sample_ratio': '采样率',
-  'PluginForm.plugin.skywalking.property.service_name': '服务名',
-
-  'PluginForm.plugin.serverless-pre-function.desc': '在指定阶段最开始的位置,运行指定的 Lua 函数',
-  'PluginForm.plugin.serverless-pre-function.property.phase': '运行阶段',
-  'PluginForm.plugin.serverless-pre-function.property.functions': '运行的函数集',
-
-  'PluginForm.plugin.serverless-post-function.desc': '在指定阶段最后的位置,运行指定的 Lua 函数',
-  'PluginForm.plugin.serverless-post-function.property.phase': '运行阶段',
-  'PluginForm.plugin.serverless-post-function.property.functions': '运行的函数集',
-
-  'PluginForm.plugin.basic-auth.desc': 'basic auth 插件',
-  'PluginForm.plugin.jwt-auth.desc': 'JWT 认证插件',
-  'PluginForm.plugin.key-auth.desc': 'key auth 插件',
-  'PluginForm.plugin.wolf-rbac.desc': '对接 wolf RBAC 服务',
-  'PluginForm.plugin.openid-connect.desc': 'Open ID Connect(OIDC) 插件提供对接外部认证服务的能力',
-
-  'PluginForm.plugin.redirect.desc': '重定向插件',
-  'PluginForm.plugin.proxy-rewrite.desc': 'proxy rewrite 代理改写插件,可以改写客户端请求',
-  'PluginForm.plugin.mqtt-proxy.desc':
-    'mqtt-proxy 插件可以帮助你根据 MQTT 的 client_id 实现动态负载均衡',
-  'PluginForm.plugin.grpc-transcoding.desc':
-    'gRPC 转换插件,实现 HTTP(s) -> APISIX -> gRPC server 的转换',
-  'PluginForm.plugin.batch-requests.desc':
-    'batch-requests 插件可以一次接受多个请求并以 http pipeline 的方式在网关发起多个 http 请求,合并结果后再返回客户端,这在客户端需要访问多个接口时可以显著地提升请求性能',
-};
diff --git a/src/components/PluginForm/locales/zh-CN.ts b/src/components/PluginForm/locales/zh-CN.ts
deleted file mode 100644
index 3efc205..0000000
--- a/src/components/PluginForm/locales/zh-CN.ts
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* eslint-disable no-template-curly-in-string */
-export default {
-  'PluginForm.plugin.limit-conn.desc': '限制并发连接数',
-  'PluginForm.plugin.limit-conn.property.conn': 'conn',
-  'PluginForm.plugin.limit-conn.property.conn.extra': '最大并发连接数',
-  'PluginForm.plugin.limit-conn.property.burst': 'burst',
-  'PluginForm.plugin.limit-conn.property.burst.extra':
-    '并发连接数超过 conn,但是低于 conn + burst 时,请求将被延迟处理',
-  'PluginForm.plugin.limit-conn.property.default_conn_delay': '延迟时间',
-  'PluginForm.plugin.limit-conn.property.default_conn_delay.extra':
-    '被延迟处理的请求,需要等待多少秒',
-  'PluginForm.plugin.limit-conn.property.key': 'key',
-  'PluginForm.plugin.limit-conn.property.key.extra': '用来做限制的依据',
-  'PluginForm.plugin.limit-conn.property.rejected_code': '拒绝状态码',
-  'PluginForm.plugin.limit-conn.property.rejected_code.extra':
-    '当并发连接数超过 conn + burst 的限制时,返回给终端的 HTTP 状态码',
-
-  'PluginForm.plugin.limit-count.desc': '在指定的时间范围内,限制总的请求次数',
-  'PluginForm.plugin.limit-count.property.count': '总请求次数',
-  'PluginForm.plugin.limit-count.property.count.extra': '指定时间窗口内的请求数量阈值',
-  'PluginForm.plugin.limit-count.property.time_window': '时间窗口',
-  'PluginForm.plugin.limit-count.property.time_window.extra':
-    '时间窗口的大小(以秒为单位),超过这个时间,总请求次数就会重置',
-  'PluginForm.plugin.limit-count.property.key': 'key',
-  'PluginForm.plugin.limit-count.property.key.extra': '用来做请求计数的依据',
-  'PluginForm.plugin.limit-count.property.rejected_code': '拒绝状态码',
-  'PluginForm.plugin.limit-count.property.rejected_code.extra':
-    '当请求超过阈值时,返回给终端的 HTTP 状态码',
-  'PluginForm.plugin.limit-count.property.policy': '策略',
-  'PluginForm.plugin.limit-count.property.redis_host': '地址',
-  'PluginForm.plugin.limit-count.property.redis_host.extra': '用于集群限流的 Redis 节点地址',
-  'PluginForm.plugin.limit-count.property.redis_port': '端口',
-  'PluginForm.plugin.limit-count.property.redis_password': '密码',
-  'PluginForm.plugin.limit-count.property.redis_timeout': '超时时间(毫秒)',
-
-  'PluginForm.plugin.limit-req.desc': '限制请求速度的插件,基于漏桶算法',
-  'PluginForm.plugin.limit-req.property.rate': 'rate',
-  'PluginForm.plugin.limit-req.property.rate.extra': '每秒请求速率',
-  'PluginForm.plugin.limit-req.property.burst': 'burst',
-  'PluginForm.plugin.limit-req.property.burst.extra':
-    '每秒请求速率超过 rate,但是低于 rate + burst 时,请求将被延迟处理',
-  'PluginForm.plugin.limit-req.property.key': 'key',
-  'PluginForm.plugin.limit-req.property.key.extra': '用来做请求计数的依据',
-  'PluginForm.plugin.limit-req.property.rejected_code': '拒绝状态码',
-  'PluginForm.plugin.limit-req.property.rejected_code.extra':
-    '速率超过 rate + burst 的限制时,返回给终端的 HTTP 状态码',
-
-  'PluginForm.plugin.cors.desc': 'CORS 插件可以为服务端启用 CORS 的返回头',
-  'PluginForm.plugin.cors.property.allow_origins': '允许跨域访问的 Origin',
-  'PluginForm.plugin.cors.property.allow_origins.extra': '比如 https://somehost.com:8081',
-  'PluginForm.plugin.cors.property.allow_methods': '允许跨域访问的 Method',
-
-  'PluginForm.plugin.fault-injection.desc': '故障注入插件,用来模拟各种后端故障和高延迟',
-  'PluginForm.plugin.fault-injection.property.http_status': 'HTTP 状态码',
-  'PluginForm.plugin.fault-injection.property.body': '响应体',
-  'PluginForm.plugin.fault-injection.property.duration': '延迟时间(秒)',
-
-  'PluginForm.plugin.http-logger.desc': 'http-logger 可以将日志数据请求推送到 HTTP/HTTPS 服务器',
-  'PluginForm.plugin.http-logger.property.uri': '日志服务器地址',
-  'PluginForm.plugin.http-logger.property.uri.extra': '比如 127.0.0.1:80/postendpoint?param=1',
-
-  'PluginForm.plugin.ip-restriction.desc':
-    'ip-restriction 可以把一批 IP 地址列入白名单或黑名单(二选一),时间复杂度是O(1),并支持用 CIDR 来表示 IP 范围',
-  'PluginForm.plugin.ip-restriction.property.whitelist': '白名单',
-  'PluginForm.plugin.ip-restriction.property.blacklist': '黑名单',
-
-  'PluginForm.plugin.kafka-logger.desc': '把接口请求日志以 JSON 的形式推送给外部 Kafka 集群',
-  'PluginForm.plugin.kafka-logger.property.broker_list': 'broker',
-  'PluginForm.plugin.kafka-logger.property.kafka_topic': 'topic',
-
-  'PluginForm.plugin.prometheus.desc': '提供符合 prometheus 数据格式的 metrics 数据',
-
-  'PluginForm.plugin.proxy-cache.desc': '代理缓存插件,缓存后端服务的响应数据',
-  'PluginForm.plugin.proxy-cache.property.cache_zone': '缓存区域名',
-  'PluginForm.plugin.proxy-cache.property.cache_zone.extra':
-    ' 本地目录为 /tmp/${区域名},修改默认区域名必须同时修改 config.yaml',
-  'PluginForm.plugin.proxy-cache.property.cache_key': '缓存 key',
-  'PluginForm.plugin.proxy-cache.property.cache_key.extra':
-    '可以使用 Nginx 变量,例如:$host, $uri',
-  'PluginForm.plugin.proxy-cache.property.cache_bypass': '跳过缓存检索',
-  'PluginForm.plugin.proxy-cache.property.cache_bypass.extra':
-    '这里可以使用 Nginx 变量,当此参数的值不为空或非0时将会跳过缓存的检索',
-  'PluginForm.plugin.proxy-cache.property.cache_method': '缓存 Method',
-  'PluginForm.plugin.proxy-cache.property.cache_http_status': '缓存响应状态码',
-  'PluginForm.plugin.proxy-cache.property.hide_cache_headers': '隐藏缓存头',
-  'PluginForm.plugin.proxy-cache.property.hide_cache_headers.extra':
-    '是否将 Expires 和 Cache-Control 响应头返回给客户端',
-  'PluginForm.plugin.proxy-cache.property.no_cache': '不缓存的数据',
-  'PluginForm.plugin.proxy-cache.property.no_cache.extra':
-    '这里可以使用 Nginx 变量, 当此参数的值不为空或非0时将不会缓存数据',
-
-  'PluginForm.plugin.proxy-mirror.desc': 'proxy mirror 代理镜像插件,提供了镜像客户端请求的能力',
-  'PluginForm.plugin.proxy-mirror.property.host': '镜像服务地址',
-  'PluginForm.plugin.proxy-mirror.property.host.extra':
-    '例如:http://127.0.0.1:9797。地址中需要包含 http 或 https,不能包含 URI 部分',
-
-  'PluginForm.plugin.response-rewrite.desc': '该插件支持修改上游服务返回的 body 和 header 信息',
-  'PluginForm.plugin.response-rewrite.property.status_code': '状态码',
-  'PluginForm.plugin.response-rewrite.property.body': '响应体',
-  'PluginForm.plugin.response-rewrite.property.body_base64': '响应体是否需要 base64 解码',
-  'PluginForm.plugin.response-rewrite.property.headers': 'HTTP 头',
-
-  'PluginForm.plugin.syslog.desc': '对接 syslog 日志服务器',
-  'PluginForm.plugin.syslog.property.host': '日志服务器地址',
-  'PluginForm.plugin.syslog.property.port': '日志服务器端口',
-  'PluginForm.plugin.syslog.property.timeout': '超时时间',
-  'PluginForm.plugin.syslog.property.tls': '开启 SSL',
-  'PluginForm.plugin.syslog.property.flush_limit': '缓存区大小',
-  'PluginForm.plugin.syslog.property.sock_type': '协议类型',
-  'PluginForm.plugin.syslog.property.max_retry_times': '重试次数',
-  'PluginForm.plugin.syslog.property.retry_interval': '重试间隔时间(毫秒)',
-  'PluginForm.plugin.syslog.property.pool_size': '连接池大小',
-
-  'PluginForm.plugin.tcp-logger.desc': '对接 TCP 日志服务器',
-  'PluginForm.plugin.tcp-logger.property.host': '日志服务器地址',
-  'PluginForm.plugin.tcp-logger.property.port': '日志服务器地址',
-  'PluginForm.plugin.tcp-logger.property.timeout': '超时时间',
-  'PluginForm.plugin.tcp-logger.property.tls': '开启 SSL',
-  'PluginForm.plugin.tcp-logger.property.tls_options': 'TLS 选型',
-
-  'PluginForm.plugin.udp-logger.desc': '对接 UDP 日志服务器',
-  'PluginForm.plugin.udp-logger.property.host': '日志服务器地址',
-  'PluginForm.plugin.udp-logger.property.port': '日志服务器地址',
-  'PluginForm.plugin.udp-logger.property.timeout': '超时时间',
-
-  'PluginForm.plugin.zipkin.desc': '对接 zipkin',
-  'PluginForm.plugin.zipkin.property.endpoint': 'endpoint',
-  'PluginForm.plugin.zipkin.property.endpoint.extra': '例如 http://127.0.0.1:9411/api/v2/spans',
-  'PluginForm.plugin.zipkin.property.sample_ratio': '采样率',
-  'PluginForm.plugin.zipkin.property.service_name': '服务名',
-  'PluginForm.plugin.zipkin.property.server_addr': '网关实例 IP',
-  'PluginForm.plugin.zipkin.property.server_addr.extra': '默认值是 Nginx 内置变量 server_addr',
-
-  'PluginForm.plugin.skywalking.desc': '对接 Apache Skywalking',
-  'PluginForm.plugin.skywalking.property.endpoint': 'endpoint',
-  'PluginForm.plugin.skywalking.property.endpoint.extra': '例如 http://127.0.0.1:12800',
-  'PluginForm.plugin.skywalking.property.sample_ratio': '采样率',
-  'PluginForm.plugin.skywalking.property.service_name': '服务名',
-
-  'PluginForm.plugin.serverless-pre-function.desc': '在指定阶段最开始的位置,运行指定的 Lua 函数',
-  'PluginForm.plugin.serverless-pre-function.property.phase': '运行阶段',
-  'PluginForm.plugin.serverless-pre-function.property.functions': '运行的函数集',
-
-  'PluginForm.plugin.serverless-post-function.desc': '在指定阶段最后的位置,运行指定的 Lua 函数',
-  'PluginForm.plugin.serverless-post-function.property.phase': '运行阶段',
-  'PluginForm.plugin.serverless-post-function.property.functions': '运行的函数集',
-
-  'PluginForm.plugin.basic-auth.desc': 'basic auth 插件',
-  'PluginForm.plugin.jwt-auth.desc': 'JWT 认证插件',
-  'PluginForm.plugin.key-auth.desc': 'key auth 插件',
-  'PluginForm.plugin.wolf-rbac.desc': '对接 wolf RBAC 服务',
-  'PluginForm.plugin.openid-connect.desc': 'Open ID Connect(OIDC) 插件提供对接外部认证服务的能力',
-
-  'PluginForm.plugin.redirect.desc': '重定向插件',
-  'PluginForm.plugin.proxy-rewrite.desc': 'proxy rewrite 代理改写插件,可以改写客户端请求',
-  'PluginForm.plugin.mqtt-proxy.desc':
-    'mqtt-proxy 插件可以帮助你根据 MQTT 的 client_id 实现动态负载均衡',
-  'PluginForm.plugin.grpc-transcoding.desc':
-    'gRPC 转换插件,实现 HTTP(s) -> APISIX -> gRPC server 的转换',
-  'PluginForm.plugin.batch-requests.desc':
-    'batch-requests 插件可以一次接受多个请求并以 http pipeline 的方式在网关发起多个 http 请求,合并结果后再返回客户端,这在客户端需要访问多个接口时可以显著地提升请求性能',
-};
diff --git a/src/components/PluginForm/service.ts b/src/components/PluginForm/service.ts
deleted file mode 100644
index 89388b6..0000000
--- a/src/components/PluginForm/service.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { request } from 'umi';
-import { transformSchemaFromAPI } from './transformer';
-
-export const fetchPluginSchema = (name: string): Promise<PluginForm.PluginSchema> =>
-  request(`/schema/plugins/${name}`).then((data) => transformSchemaFromAPI(data, name));
diff --git a/src/components/PluginForm/transformer.ts b/src/components/PluginForm/transformer.ts
deleted file mode 100644
index 031da2f..0000000
--- a/src/components/PluginForm/transformer.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { v4 as uuidv4 } from 'uuid';
-import { Rule } from 'antd/es/form';
-
-/**
- * Transform schema data from API for target plugin.
- */
-export const transformSchemaFromAPI = (
-  schema: PluginForm.PluginSchema,
-  pluginName: string,
-): PluginForm.PluginSchema => {
-  if (pluginName === 'key-auth') {
-    return {
-      ...schema,
-      properties: {
-        key: {
-          ...schema.properties!.key,
-          default: uuidv4(),
-        },
-      },
-    };
-  }
-
-  if (pluginName === 'prometheus' || pluginName === 'node-status' || pluginName === 'heartbeat') {
-    return {
-      ...schema,
-      properties: {
-        enabled: {
-          type: 'boolean',
-          default: false,
-        },
-      },
-    };
-  }
-
-  return schema;
-};
-
-/**
- * Transform schema data to be compatible with API.
- */
-// eslint-disable-next-line arrow-body-style
-export const transformSchemaToAPI = (schema: PluginForm.PluginSchema, pluginName: string) => {
-  return { schema, pluginName };
-};
-
-/**
- * Transform schema's property to rules.
- */
-export const transformPropertyToRules = (
-  schema: PluginForm.PluginSchema,
-  propertyName: string,
-  propertyValue: PluginForm.PluginProperty,
-): Rule[] => {
-  if (!schema) {
-    return [];
-  }
-
-  const { type, minLength, maxLength, minimum, maximum, pattern } = propertyValue;
-
-  const requiredRule = schema.required?.includes(propertyName) ? [{ required: true }] : [];
-  const typeRule = [{ type }];
-  const enumRule = propertyValue.enum ? [{ type: 'enum', enum: propertyValue.enum }] : [];
-  const rangeRule =
-    type !== 'string' &&
-    type !== 'array' &&
-    (propertyValue.hasOwnProperty('minimum') || propertyValue.hasOwnProperty('maximum'))
-      ? [
-          {
-            min: minimum ?? Number.MIN_SAFE_INTEGER,
-            max: maximum ?? Number.MAX_SAFE_INTEGER,
-          },
-        ]
-      : [];
-  const lengthRule =
-    type === 'string' || type === 'array'
-      ? [{ min: minLength ?? Number.MIN_SAFE_INTEGER, max: maxLength ?? Number.MAX_SAFE_INTEGER }]
-      : [];
-  const customPattern = pattern ? [{ pattern: new RegExp(pattern) }] : [];
-
-  const rules = [
-    ...requiredRule,
-    ...typeRule,
-    ...enumRule,
-    ...rangeRule,
-    ...lengthRule,
-    ...customPattern,
-  ];
-  const flattend = rules.reduce((prev, next) => ({ ...prev, ...next }));
-  return [flattend] as Rule[];
-};
diff --git a/src/components/PluginForm/typing.d.ts b/src/components/PluginForm/typing.d.ts
deleted file mode 100644
index caf6e99..0000000
--- a/src/components/PluginForm/typing.d.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-declare namespace PluginForm {
-  interface Props {
-    name?: string;
-    disabled?: boolean;
-    // FormInstance
-    form: any;
-    initialData?: PluginSchema;
-    onFinish(values: any): void;
-  }
-
-  interface PluginSchema {
-    type: 'object';
-    id?: string;
-    required?: string[];
-    additionalProperties?: boolean;
-    minProperties?: number;
-    oneOf?: Array<{
-      required: string[];
-    }>;
-    properties?: {
-      [propertyName: string]: PluginProperty;
-    };
-  }
-
-  interface PluginProperty {
-    type: 'number' | 'string' | 'integer' | 'array' | 'boolean' | 'object';
-    // the same as type
-    default?: any;
-    description?: string;
-    // NOTE: maybe 0.00001
-    minimum?: number;
-    maximum?: number;
-    minLength?: number;
-    maxLength?: number;
-    minItems?: number;
-    maxItems?: number;
-    // e.g "^/.*"
-    pattern?: string;
-    enum?: string[];
-    requried?: string[];
-    minProperties?: number;
-    additionalProperties?: boolean;
-    items?: {
-      type: string;
-      anyOf?: Array<{
-        type?: string;
-        description?: string;
-        enum?: string[];
-        pattern?: string;
-      }>;
-    };
-  }
-
-  type PluginCategory = 'Security' | 'Limit' | 'Log' | 'Metric' | 'Other';
-
-  type PluginMapperItem = {
-    category: PluginCategory;
-    hidden?: boolean;
-  };
-
-  interface PluginProps extends PluginMapperItem {
-    name: string;
-  }
-}
diff --git a/src/components/PluginModal/index.tsx b/src/components/PluginModal/index.tsx
deleted file mode 100644
index fbd8bed..0000000
--- a/src/components/PluginModal/index.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-import { Modal, Form } from 'antd';
-import { useIntl } from 'umi';
-
-import PluginForm from '@/components/PluginForm';
-
-interface Props {
-  visible: boolean;
-  name: string;
-  initialData?: PluginForm.PluginSchema;
-  onFinish(values: any): void;
-}
-
-const PluginModal: React.FC<Props> = (props) => {
-  const { name, visible } = props;
-  const [form] = Form.useForm();
-
-  return (
-    <Modal
-      destroyOnClose
-      visible={visible}
-      title={`${useIntl().formatMessage({ id: 'component.global.edit.plugin' })} ${name}`}
-      okText="确定"
-      cancelText="取消"
-    >
-      <PluginForm form={form} {...props} />
-    </Modal>
-  );
-};
-
-export default PluginModal;
diff --git a/src/components/PluginPage/PluginCard.tsx b/src/components/PluginPage/PluginCard.tsx
deleted file mode 100644
index ae98731..0000000
--- a/src/components/PluginPage/PluginCard.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React from 'react';
-import { Card } from 'antd';
-import { CardProps } from 'antd/lib/card';
-import { useIntl } from 'umi';
-
-interface Props extends CardProps {
-  name: string;
-}
-
-const PluginCard: React.FC<Props> = ({ name, actions }) => {
-  const { formatMessage } = useIntl();
-
-  return (
-    <Card actions={actions}>
-      <Card.Meta
-        title={name}
-        description={formatMessage({
-          id: `PluginPage.card.${name}.desc`,
-          defaultMessage: formatMessage({ id: 'PluginPage.card.refer.documents' }),
-        })}
-      />
-    </Card>
-  );
-};
-
-export default PluginCard;
diff --git a/src/components/PluginPage/PluginDrawer.tsx b/src/components/PluginPage/PluginDrawer.tsx
deleted file mode 100644
index 2f85594..0000000
--- a/src/components/PluginPage/PluginDrawer.tsx
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, { Fragment } from 'react';
-import { Drawer, Button } from 'antd';
-import { withTheme, FormProps } from '@rjsf/core';
-import { Theme as AntDTheme } from '@rjsf/antd';
-import { JSONSchema7 } from 'json-schema';
-import { useIntl } from 'umi';
-
-interface Props {
-  name?: string;
-  initialData: any;
-  active?: boolean;
-  disabled?: boolean;
-  schema: JSONSchema7;
-  onActive(name: string): void;
-  onInactive(name: string): void;
-  onClose(): void;
-  onFinish(values: any): void;
-}
-
-const PluginDrawer: React.FC<Props> = ({
-  name,
-  active,
-  disabled,
-  schema,
-  initialData,
-  onActive,
-  onInactive,
-  onClose,
-  onFinish,
-}) => {
-  const { formatMessage } = useIntl();
-  const PluginForm = withTheme(AntDTheme);
-
-  if (!name) {
-    return null;
-  }
-
-  // NOTE: 用于作为 PluginForm 的引用
-  let form: any;
-
-  return (
-    <Drawer
-      title={formatMessage({ id: 'PluginPage.drawer.configure.plugin' })}
-      width={400}
-      visible={Boolean(name)}
-      destroyOnClose
-      onClose={onClose}
-      footer={
-        disabled ? null : (
-          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-            <div>
-              {Boolean(active) && (
-                <Button type="primary" danger onClick={() => onInactive(name)}>
-                  {formatMessage({ id: 'PluginPage.drawer.disabled' })}
-                </Button>
-              )}
-              {Boolean(!active) && (
-                <Button type="primary" onClick={() => onActive(name)}>
-                  {formatMessage({ id: 'PluginPage.drawer.enable' })}
-                </Button>
-              )}
-            </div>
-            {Boolean(active) && (
-              <div>
-                <Button onClick={onClose}>
-                  {formatMessage({ id: 'PluginPage.drawer.cancel' })}
-                </Button>
-                <Button
-                  type="primary"
-                  style={{ marginRight: 8, marginLeft: 8 }}
-                  onClick={() => {
-                    form.submit();
-                  }}
-                >
-                  {formatMessage({ id: 'PluginPage.drawer.confirm' })}
-                </Button>
-              </div>
-            )}
-          </div>
-        )
-      }
-    >
-      <PluginForm
-        schema={schema}
-        liveValidate
-        disabled={disabled || !active}
-        formData={initialData}
-        showErrorList={false}
-        ref={(_form: FormProps<any>) => {
-          form = _form;
-        }}
-        onSubmit={({ formData }) => {
-          onFinish(formData);
-        }}
-      >
-        {/* NOTE: 留空,用于隐藏 Submit 按钮 */}
-        <Fragment />
-      </PluginForm>
-    </Drawer>
-  );
-};
-
-export default PluginDrawer;
diff --git a/src/components/PluginPage/PluginPage.tsx b/src/components/PluginPage/PluginPage.tsx
deleted file mode 100644
index aee0a7b..0000000
--- a/src/components/PluginPage/PluginPage.tsx
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, { useState, useEffect } from 'react';
-import { LinkOutlined, SettingOutlined } from '@ant-design/icons';
-import { omit } from 'lodash';
-import { JSONSchema7 } from 'json-schema';
-
-import PanelSection from '@/components/PanelSection';
-
-import PluginCard from './PluginCard';
-import PluginDrawer from './PluginDrawer';
-import { getList, fetchPluginSchema } from './service';
-import { PLUGIN_MAPPER_SOURCE } from './data';
-import { useIntl } from 'umi';
-
-type Props = {
-  disabled?: boolean;
-  data: PluginPage.PluginData;
-  onChange?(data: PluginPage.PluginData): void;
-};
-
-const PluginPage: React.FC<Props> = ({ data = {}, disabled, onChange }) => {
-  const [pluginName, setPluginName] = useState<string | undefined>();
-  const [activeList, setActiveList] = useState<PluginPage.PluginProps[]>([]);
-  const [inactiveList, setInactiveList] = useState<PluginPage.PluginProps[]>([]);
-  const [schema, setSchema] = useState<JSONSchema7>();
-  const { formatMessage } = useIntl();
-
-  const pluginList = [
-    {
-      title: formatMessage({ id: 'PluginPage.drawer.is.enabled' }),
-      list: activeList,
-    },
-    {
-      title: formatMessage({ id: 'PluginPage.drawer.not.enabled' }),
-      list: inactiveList,
-    },
-  ];
-
-  useEffect(() => {
-    getList(data).then((props) => {
-      setActiveList(props.activeList);
-      setInactiveList(props.inactiveList);
-    });
-  }, []);
-
-  return (
-    <>
-      {pluginList.map(({ list, title }) => {
-        if (disabled && title === formatMessage({ id: 'PluginPage.drawer.not.enabled' })) {
-          return null;
-        }
-        return (
-          <PanelSection
-            title={title}
-            key={title}
-            style={{
-              display: 'grid',
-              gridTemplateColumns: 'repeat(3, 33.333%)',
-              gridRowGap: 10,
-              gridColumnGap: 10,
-            }}
-          >
-            {list.map(({ name }) => (
-              <PluginCard
-                name={name}
-                actions={[
-                  <SettingOutlined
-                    onClick={() => {
-                      fetchPluginSchema(name).then((schemaData) => {
-                        setSchema(schemaData);
-                        setTimeout(() => {
-                          setPluginName(name);
-                        }, 300);
-                      });
-                    }}
-                  />,
-                  <LinkOutlined
-                    onClick={() =>
-                      window.open(
-                        `https://github.com/apache/apisix/blob/master/doc/plugins/${name}.md`,
-                      )
-                    }
-                  />,
-                ]}
-                key={name}
-              />
-            ))}
-          </PanelSection>
-        );
-      })}
-
-      <PluginDrawer
-        name={pluginName}
-        initialData={pluginName ? data[pluginName] : {}}
-        active={Boolean(activeList.find((item) => item.name === pluginName))}
-        schema={schema!}
-        disabled={disabled}
-        onActive={(name) => {
-          // TODO: 需测试诸如 普罗米修斯 此类只需通过 {} 即可启用的插件
-          setActiveList(activeList.concat({ name, ...PLUGIN_MAPPER_SOURCE[name] }));
-          setInactiveList(inactiveList.filter((item) => item.name !== name));
-        }}
-        onInactive={(name) => {
-          if (!onChange) {
-            throw new Error('请提供 onChange 方法');
-          }
-          onChange(omit({ ...data }, name));
-          setInactiveList(inactiveList.concat({ name, ...PLUGIN_MAPPER_SOURCE[name] }));
-          setActiveList(activeList.filter((item) => item.name !== name));
-          setPluginName(undefined);
-        }}
-        onClose={() => setPluginName(undefined)}
-        onFinish={(value) => {
-          if (!pluginName) {
-            return;
-          }
-          if (!onChange) {
-            throw new Error('请提供 onChange 方法');
-          }
-          onChange({ ...data, [pluginName]: value });
-          setPluginName(undefined);
-        }}
-      />
-    </>
-  );
-};
-
-export default PluginPage;
diff --git a/src/components/PluginPage/data.ts b/src/components/PluginPage/data.ts
deleted file mode 100644
index b61190a..0000000
--- a/src/components/PluginPage/data.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export const PLUGIN_MAPPER_SOURCE: { [name: string]: PluginPage.PluginMapperItem } = {
-  'limit-req': {
-    category: 'Limit',
-  },
-  'limit-count': {
-    category: 'Limit',
-  },
-  'limit-conn': {
-    category: 'Limit',
-  },
-  'key-auth': {
-    category: 'Security',
-  },
-  'basic-auth': {
-    category: 'Security',
-  },
-  prometheus: {
-    category: 'Metric',
-  },
-  'node-status': {
-    category: 'Other',
-  },
-  'jwt-auth': {
-    category: 'Security',
-  },
-  zipkin: {
-    category: 'Metric',
-  },
-  'ip-restriction': {
-    category: 'Security',
-  },
-  'grpc-transcode': {
-    category: 'Other',
-    hidden: true,
-  },
-  'serverless-pre-function': {
-    category: 'Other',
-  },
-  'serverless-post-function': {
-    category: 'Other',
-  },
-  'openid-connect': {
-    category: 'Security',
-  },
-  'proxy-rewrite': {
-    category: 'Other',
-    hidden: true,
-  },
-  redirect: {
-    category: 'Other',
-    hidden: true,
-  },
-  'response-rewrite': {
-    category: 'Other',
-  },
-  'fault-injection': {
-    category: 'Security',
-  },
-  'udp-logger': {
-    category: 'Log',
-  },
-  'wolf-rbac': {
-    category: 'Other',
-    hidden: true,
-  },
-  'proxy-cache': {
-    category: 'Other',
-  },
-  'tcp-logger': {
-    category: 'Log',
-  },
-  'proxy-mirror': {
-    category: 'Other',
-  },
-  'kafka-logger': {
-    category: 'Log',
-  },
-  cors: {
-    category: 'Security',
-  },
-  heartbeat: {
-    category: 'Other',
-    hidden: true,
-  },
-  'batch-requests': {
-    category: 'Other',
-  },
-  'http-logger': {
-    category: 'Log',
-  },
-  'mqtt-proxy': {
-    category: 'Other',
-  },
-  oauth: {
-    category: 'Security',
-  },
-};
diff --git a/src/components/PluginPage/index.ts b/src/components/PluginPage/index.ts
deleted file mode 100644
index 7c7bd64..0000000
--- a/src/components/PluginPage/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export { default } from './PluginPage';
-export { default as PluginCard } from './PluginCard';
-export { default as PluginDrawer } from './PluginDrawer';
-
-export { default as PluginPageZhCN } from './locales/zh-CN';
-export { default as PluginPageEnUS } from './locales/en-US';
diff --git a/src/components/PluginPage/locales/en-US.ts b/src/components/PluginPage/locales/en-US.ts
deleted file mode 100644
index 3efcf00..0000000
--- a/src/components/PluginPage/locales/en-US.ts
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export default {
-  'PluginPage.card.limit-conn.desc': 'Limit the number of concurrent connections',
-  'PluginPage.card.limit-conn.property.conn': 'conn',
-  'PluginPage.card.limit-conn.property.conn.extra': 'Maximum number of concurrent connections',
-  'PluginPage.card.limit-conn.property.burst': 'burst',
-  'PluginPage.card.limit-conn.property.burst.extra':
-    'When the number of concurrent connections more than conn but less than burst, the request will be delayed',
-  'PluginPage.card.limit-conn.property.default_conn_delay': 'delay time',
-  'PluginPage.card.limit-conn.property.default_conn_delay.extra':
-    'Waiting time(seconds) for requests being delayed',
-  'PluginPage.card.limit-conn.property.key': 'key',
-  'PluginPage.card.limit-conn.property.key.extra': 'Basis of restriction',
-  'PluginPage.card.limit-conn.property.rejected_code': 'Reject status code',
-  'PluginPage.card.limit-conn.property.rejected_code.extra':
-    'When the number of concurrent connections more than conn + burst, HTTP status code will be returned to the terminal',
-
-  'PluginPage.card.limit-count.desc': 'Limit the total requests within the specified time range',
-  'PluginPage.card.limit-count.property.count': 'Total requests',
-  'PluginPage.card.limit-count.property.count.extra': 'Threshold for the number of requests within a specified time window',
-  'PluginPage.card.limit-count.property.time_window': 'Time window',
-  'PluginPage.card.limit-count.property.time_window.extra':
-    'When the size of time window(seconds) is exceeded, the total number of requests will be reset',
-  'PluginPage.card.limit-count.property.key': 'key',
-  'PluginPage.card.limit-count.property.key.extra': 'Basis of request count',
-  'PluginPage.card.limit-count.property.rejected_code': 'Reject status code',
-  'PluginPage.card.limit-count.property.rejected_code.extra':
-    'When the requests exceed threshold, HTTP status code will be returned to the terminal',
-  'PluginPage.card.limit-count.property.policy': 'policy',
-  'PluginPage.card.limit-count.property.redis_host': 'host address',
-  'PluginPage.card.limit-count.property.redis_host.extra': 'Redis node address for cluster flow limited',
-  'PluginPage.card.limit-count.property.redis_port': 'port',
-  'PluginPage.card.limit-count.property.redis_password': 'password',
-  'PluginPage.card.limit-count.property.redis_timeout': 'timeout(millisecond)',
-
-  'PluginPage.card.limit-req.desc': 'A plugin which is base leaky bucket algorithm to limit the speed of requests',
-  'PluginPage.card.limit-req.property.rate': 'rate',
-  'PluginPage.card.limit-req.property.rate.extra': 'Request rate per second',
-  'PluginPage.card.limit-req.property.burst': 'burst',
-  'PluginPage.card.limit-req.property.burst.extra':
-    'When request rate per second exceed date but blow rate + burst, the request will be delayed',
-  'PluginPage.card.limit-req.property.key': 'key',
-  'PluginPage.card.limit-req.property.key.extra': 'Basis of request count',
-  'PluginPage.card.limit-req.property.rejected_code': 'Reject status code',
-  'PluginPage.card.limit-req.property.rejected_code.extra':
-    'When the rate exceed rate + burst, HTTP status code will be returned to the terminal',
-
-  'PluginPage.card.cors.desc': 'The CORS plugin can enable the return header of CORS for the server',
-  'PluginPage.card.cors.property.allow_origins': 'The origin which allow cross-domain access',
-  'PluginPage.card.cors.property.allow_origins.extra': 'For example: https://somehost.com:8081',
-  'PluginPage.card.cors.property.allow_methods': 'The method which allow cross-domain access',
-
-  'PluginPage.card.fault-injection.desc': 'Fault-injection plugin used to simulate various backend failures and high latency',
-  'PluginPage.card.fault-injection.property.http_status': 'HTTP status code',
-  'PluginPage.card.fault-injection.property.body': 'response body',
-  'PluginPage.card.fault-injection.property.duration': 'delay time(seconds)',
-
-  'PluginPage.card.http-logger.desc': 'http-logger can push log data requests to the HTTP/HTTPS server',
-  'PluginPage.card.http-logger.property.uri': 'log server address',
-  'PluginPage.card.http-logger.property.uri.extra': 'For example: 127.0.0.1:80/postendpoint?param=1',
-
-  'PluginPage.card.ip-restriction.desc':
-    'IP-restriction can add a batch of IP addresses in whitelist or blacklist(either), time complexity is O(1), and can use CIDR to represent IP range',
-  'PluginPage.card.ip-restriction.property.whitelist': 'whitelist',
-  'PluginPage.card.ip-restriction.property.blacklist': 'blacklist',
-
-  'PluginPage.card.kafka-logger.desc': 'Push the interface request logs as JSON to the external Kafka clusters',
-  'PluginPage.card.kafka-logger.property.broker_list': 'broker',
-  'PluginPage.card.kafka-logger.property.kafka_topic': 'topic',
-
-  'PluginPage.card.prometheus.desc': 'Provide metrics data which is accord with prometheus data formate',
-
-  'PluginPage.card.proxy-cache.desc': 'Proxy-cache plugin can cache the response data of the backend service',
-  'PluginPage.card.proxy-cache.property.cache_zone': 'cache area name',
-  'PluginPage.card.proxy-cache.property.cache_zone.extra':
-    'The local directory is /TMP/{area name}, when modify the default area name, config.yaml must be modified too',
-  'PluginPage.card.proxy-cache.property.cache_key': 'cache key',
-  'PluginPage.card.proxy-cache.property.cache_key.extra':
-    'can use Nginx variables, for example: $host, $uri',
-  'PluginPage.card.proxy-cache.property.cache_bypass': 'skip cache retrieval',
-  'PluginPage.card.proxy-cache.property.cache_bypass.extra':
-    'You can use the Nginx variables here, when the value of this parameter is not null or non-zero, it will skip cache retrieval',
-  'PluginPage.card.proxy-cache.property.cache_method': 'cache Method',
-  'PluginPage.card.proxy-cache.property.cache_http_status': 'cache the response status code',
-  'PluginPage.card.proxy-cache.property.hide_cache_headers': 'hidden cache header',
-  'PluginPage.card.proxy-cache.property.hide_cache_headers.extra':
-    'Whether to return Expires and Cache-Control response headers to the client',
-  'PluginPage.card.proxy-cache.property.no_cache': 'uncached data',
-  'PluginPage.card.proxy-cache.property.no_cache.extra':
-    'You can use the Nginx variables here, when the value of this parameter is not null or non-zero, it will not be cached',
-
-  'PluginPage.card.proxy-mirror.desc': 'Proxy-mirror plugin provides the ability to mirror client',
-  'PluginPage.card.proxy-mirror.property.host': 'mirror service address',
-  'PluginPage.card.proxy-mirror.property.host.extra':
-    'For example: http://127.0.0.1:9797. Address need to include HTTP or HTTPS but not include the URI part',
-
-  'PluginPage.card.response-rewrite.desc': 'The plugin supports modifying the body and header information returned by the upstream service',
-  'PluginPage.card.response-rewrite.property.status_code': 'status code',
-  'PluginPage.card.response-rewrite.property.body': 'response body',
-  'PluginPage.card.response-rewrite.property.body_base64': 'Whether the response body requires base64 decoding',
-  'PluginPage.card.response-rewrite.property.headers': 'HTTP header',
-
-  'PluginPage.card.syslog.desc': 'Relate to the syslog log server',
-  'PluginPage.card.syslog.property.host': 'log server address',
-  'PluginPage.card.syslog.property.port': 'log server port',
-  'PluginPage.card.syslog.property.timeout': 'timeout',
-  'PluginPage.card.syslog.property.tls': 'open SSL',
-  'PluginPage.card.syslog.property.flush_limit': 'cache size',
-  'PluginPage.card.syslog.property.sock_type': 'protocol type',
-  'PluginPage.card.syslog.property.max_retry_times': 'number of retries',
-  'PluginPage.card.syslog.property.retry_interval': 'retry interval(milliseconds)',
-  'PluginPage.card.syslog.property.pool_size': 'connection pool size',
-
-  'PluginPage.card.tcp-logger.desc': 'Relate to the TCP log server',
-  'PluginPage.card.tcp-logger.property.host': 'log server address',
-  'PluginPage.card.tcp-logger.property.port': 'log server port',
-  'PluginPage.card.tcp-logger.property.timeout': 'timeout',
-  'PluginPage.card.tcp-logger.property.tls': 'open SSL',
-  'PluginPage.card.tcp-logger.property.tls_options': 'TLS selection',
-
-  'PluginPage.card.udp-logger.desc': 'Relate to the UDP log server',
-  'PluginPage.card.udp-logger.property.host': 'log server address',
-  'PluginPage.card.udp-logger.property.port': 'log server port',
-  'PluginPage.card.udp-logger.property.timeout': 'timeout',
-
-  'PluginPage.card.zipkin.desc': 'Relate to zipkin',
-  'PluginPage.card.zipkin.property.endpoint': 'endpoint',
-  'PluginPage.card.zipkin.property.endpoint.extra': 'For example: http://127.0.0.1:9411/api/v2/spans',
-  'PluginPage.card.zipkin.property.sample_ratio': 'sampling rate',
-  'PluginPage.card.zipkin.property.service_name': 'service name',
-  'PluginPage.card.zipkin.property.server_addr': 'gateway instance IP',
-  'PluginPage.card.zipkin.property.server_addr.extra': 'default value is Nginx variable server_addr',
-
-  'PluginPage.card.skywalking.desc': 'Relate to Apache Skywalking',
-  'PluginPage.card.skywalking.property.endpoint': 'endpoint',
-  'PluginPage.card.skywalking.property.endpoint.extra': 'For example: http://127.0.0.1:12800',
-  'PluginPage.card.skywalking.property.sample_ratio': 'sampling rate',
-  'PluginPage.card.skywalking.property.service_name': 'service name',
-
-  'PluginPage.card.serverless-pre-function.desc': 'Runs the specified Lua function at the beginning of the specified phase',
-  'PluginPage.card.serverless-pre-function.property.phase': 'run phase',
-  'PluginPage.card.serverless-pre-function.property.functions': 'the set of functions to run',
-
-  'PluginPage.card.serverless-post-function.desc': 'Runs the specified Lua function at the ending of the specified phase',
-  'PluginPage.card.serverless-post-function.property.phase': 'run phase',
-  'PluginPage.card.serverless-post-function.property.functions': 'the set of functions to run',
-
-  'PluginPage.card.basic-auth.desc': 'basic auth plugin',
-  'PluginPage.card.jwt-auth.desc': 'JWT authentication plugin',
-  'PluginPage.card.key-auth.desc': 'key auth plugin',
-  'PluginPage.card.wolf-rbac.desc': 'Relate to wolf RBAC service',
-  'PluginPage.card.openid-connect.desc': 'Open ID Connect(OIDC) plugin provide the ability to deal with external certification services',
-
-  'PluginPage.card.redirect.desc': 'redirect plugin',
-  'PluginPage.card.proxy-rewrite.desc': 'proxy rewrite plugin, which can rewrite client request',
-  'PluginPage.card.mqtt-proxy.desc':
-    'mqtt-proxy plugin can achieve load balancing based on client_id of MQTT',
-  'PluginPage.card.grpc-transcoding.desc':
-    'gRPC transform plugin can achieve HTTP(s) -> APISIX -> gRPC server',
-  'PluginPage.card.batch-requests.desc':
-    'batch-requests plugin can accept multiple requests at one time and initiate mutiple HTTP requests in the way of HTTP pipeline, merge the resules and return to client, which can significantly improve the request performance when the client needs to access multiple interfaces',
-
-  'PluginPage.card.node-status.desc': 'node-status',
-  'PluginPage.card.refer.documents':'Please refer to the official documents',
-  
-  'PluginPage.drawer.configure.plugin':'Configure plugin',
-  'PluginPage.drawer.disabled':'Disabled',
-  'PluginPage.drawer.enable':'Enable',
-  'PluginPage.drawer.cancel':'Cancel',
-  'PluginPage.drawer.confirm':'Confirm',
-  'PluginPage.drawer.is.enabled':'Is Enabled',
-  'PluginPage.drawer.not.enabled':'Not Enabled',
-};
\ No newline at end of file
diff --git a/src/components/PluginPage/locales/zh-CN.ts b/src/components/PluginPage/locales/zh-CN.ts
deleted file mode 100644
index 810cca2..0000000
--- a/src/components/PluginPage/locales/zh-CN.ts
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export default {
-  'PluginPage.card.limit-conn.desc': '限制并发连接数',
-  'PluginPage.card.limit-conn.property.conn': 'conn',
-  'PluginPage.card.limit-conn.property.conn.extra': '最大并发连接数',
-  'PluginPage.card.limit-conn.property.burst': 'burst',
-  'PluginPage.card.limit-conn.property.burst.extra':
-    '并发连接数超过 conn,但是低于 conn + burst 时,请求将被延迟处理',
-  'PluginPage.card.limit-conn.property.default_conn_delay': '延迟时间',
-  'PluginPage.card.limit-conn.property.default_conn_delay.extra':
-    '被延迟处理的请求,需要等待多少秒',
-  'PluginPage.card.limit-conn.property.key': 'key',
-  'PluginPage.card.limit-conn.property.key.extra': '用来做限制的依据',
-  'PluginPage.card.limit-conn.property.rejected_code': '拒绝状态码',
-  'PluginPage.card.limit-conn.property.rejected_code.extra':
-    '当并发连接数超过 conn + burst 的限制时,返回给终端的 HTTP 状态码',
-
-  'PluginPage.card.limit-count.desc': '在指定的时间范围内,限制总的请求次数',
-  'PluginPage.card.limit-count.property.count': '总请求次数',
-  'PluginPage.card.limit-count.property.count.extra': '指定时间窗口内的请求数量阈值',
-  'PluginPage.card.limit-count.property.time_window': '时间窗口',
-  'PluginPage.card.limit-count.property.time_window.extra':
-    '时间窗口的大小(以秒为单位),超过这个时间,总请求次数就会重置',
-  'PluginPage.card.limit-count.property.key': 'key',
-  'PluginPage.card.limit-count.property.key.extra': '用来做请求计数的依据',
-  'PluginPage.card.limit-count.property.rejected_code': '拒绝状态码',
-  'PluginPage.card.limit-count.property.rejected_code.extra':
-    '当请求超过阈值时,返回给终端的 HTTP 状态码',
-  'PluginPage.card.limit-count.property.policy': '策略',
-  'PluginPage.card.limit-count.property.redis_host': '地址',
-  'PluginPage.card.limit-count.property.redis_host.extra': '用于集群限流的 Redis 节点地址',
-  'PluginPage.card.limit-count.property.redis_port': '端口',
-  'PluginPage.card.limit-count.property.redis_password': '密码',
-  'PluginPage.card.limit-count.property.redis_timeout': '超时时间(毫秒)',
-
-  'PluginPage.card.limit-req.desc': '限制请求速度的插件,基于漏桶算法',
-  'PluginPage.card.limit-req.property.rate': 'rate',
-  'PluginPage.card.limit-req.property.rate.extra': '每秒请求速率',
-  'PluginPage.card.limit-req.property.burst': 'burst',
-  'PluginPage.card.limit-req.property.burst.extra':
-    '每秒请求速率超过 rate,但是低于 rate + burst 时,请求将被延迟处理',
-  'PluginPage.card.limit-req.property.key': 'key',
-  'PluginPage.card.limit-req.property.key.extra': '用来做请求计数的依据',
-  'PluginPage.card.limit-req.property.rejected_code': '拒绝状态码',
-  'PluginPage.card.limit-req.property.rejected_code.extra':
-    '速率超过 rate + burst 的限制时,返回给终端的 HTTP 状态码',
-
-  'PluginPage.card.cors.desc': 'CORS 插件可以为服务端启用 CORS 的返回头',
-  'PluginPage.card.cors.property.allow_origins': '允许跨域访问的 Origin',
-  'PluginPage.card.cors.property.allow_origins.extra': '比如:https://somehost.com:8081',
-  'PluginPage.card.cors.property.allow_methods': '允许跨域访问的 Method',
-
-  'PluginPage.card.fault-injection.desc': '故障注入插件,用来模拟各种后端故障和高延迟',
-  'PluginPage.card.fault-injection.property.http_status': 'HTTP 状态码',
-  'PluginPage.card.fault-injection.property.body': '响应体',
-  'PluginPage.card.fault-injection.property.duration': '延迟时间(秒)',
-
-  'PluginPage.card.http-logger.desc': 'http-logger 可以将日志数据请求推送到 HTTP/HTTPS 服务器',
-  'PluginPage.card.http-logger.property.uri': '日志服务器地址',
-  'PluginPage.card.http-logger.property.uri.extra': '比如:127.0.0.1:80/postendpoint?param=1',
-
-  'PluginPage.card.ip-restriction.desc':
-    'ip-restriction 可以把一批 IP 地址列入白名单或黑名单(二选一),时间复杂度是O(1),并支持用 CIDR 来表示 IP 范围',
-  'PluginPage.card.ip-restriction.property.whitelist': '白名单',
-  'PluginPage.card.ip-restriction.property.blacklist': '黑名单',
-
-  'PluginPage.card.kafka-logger.desc': '把接口请求日志以 JSON 的形式推送给外部 Kafka 集群',
-  'PluginPage.card.kafka-logger.property.broker_list': 'broker',
-  'PluginPage.card.kafka-logger.property.kafka_topic': 'topic',
-
-  'PluginPage.card.prometheus.desc': '提供符合 prometheus 数据格式的 metrics 数据',
-
-  'PluginPage.card.proxy-cache.desc': '代理缓存插件,缓存后端服务的响应数据',
-  'PluginPage.card.proxy-cache.property.cache_zone': '缓存区域名',
-  'PluginPage.card.proxy-cache.property.cache_zone.extra':
-    ' 本地目录为 /tmp/区域名,修改默认区域名必须同时修改 config.yaml',
-  'PluginPage.card.proxy-cache.property.cache_key': '缓存 key',
-  'PluginPage.card.proxy-cache.property.cache_key.extra':
-    '可以使用 Nginx 变量,例如:$host, $uri',
-  'PluginPage.card.proxy-cache.property.cache_bypass': '跳过缓存检索',
-  'PluginPage.card.proxy-cache.property.cache_bypass.extra':
-    '这里可以使用 Nginx 变量,当此参数的值不为空或非0时将会跳过缓存的检索',
-  'PluginPage.card.proxy-cache.property.cache_method': '缓存 Method',
-  'PluginPage.card.proxy-cache.property.cache_http_status': '缓存响应状态码',
-  'PluginPage.card.proxy-cache.property.hide_cache_headers': '隐藏缓存头',
-  'PluginPage.card.proxy-cache.property.hide_cache_headers.extra':
-    '是否将 Expires 和 Cache-Control 响应头返回给客户端',
-  'PluginPage.card.proxy-cache.property.no_cache': '不缓存的数据',
-  'PluginPage.card.proxy-cache.property.no_cache.extra':
-    '这里可以使用 Nginx 变量, 当此参数的值不为空或非0时将不会缓存数据',
-
-  'PluginPage.card.proxy-mirror.desc': 'proxy mirror 代理镜像插件,提供了镜像客户端请求的能力',
-  'PluginPage.card.proxy-mirror.property.host': '镜像服务地址',
-  'PluginPage.card.proxy-mirror.property.host.extra':
-    '例如:http://127.0.0.1:9797。地址中需要包含 http 或 https,不能包含 URI 部分',
-
-  'PluginPage.card.response-rewrite.desc': '该插件支持修改上游服务返回的 body 和 header 信息',
-  'PluginPage.card.response-rewrite.property.status_code': '状态码',
-  'PluginPage.card.response-rewrite.property.body': '响应体',
-  'PluginPage.card.response-rewrite.property.body_base64': '响应体是否需要 base64 解码',
-  'PluginPage.card.response-rewrite.property.headers': 'HTTP 头',
-
-  'PluginPage.card.syslog.desc': '对接 syslog 日志服务器',
-  'PluginPage.card.syslog.property.host': '日志服务器地址',
-  'PluginPage.card.syslog.property.port': '日志服务器端口',
-  'PluginPage.card.syslog.property.timeout': '超时时间',
-  'PluginPage.card.syslog.property.tls': '开启 SSL',
-  'PluginPage.card.syslog.property.flush_limit': '缓存区大小',
-  'PluginPage.card.syslog.property.sock_type': '协议类型',
-  'PluginPage.card.syslog.property.max_retry_times': '重试次数',
-  'PluginPage.card.syslog.property.retry_interval': '重试间隔时间(毫秒)',
-  'PluginPage.card.syslog.property.pool_size': '连接池大小',
-
-  'PluginPage.card.tcp-logger.desc': '对接 TCP 日志服务器',
-  'PluginPage.card.tcp-logger.property.host': '日志服务器地址',
-  'PluginPage.card.tcp-logger.property.port': '日志服务器端口',
-  'PluginPage.card.tcp-logger.property.timeout': '超时时间',
-  'PluginPage.card.tcp-logger.property.tls': '开启 SSL',
-  'PluginPage.card.tcp-logger.property.tls_options': 'TLS 选型',
-
-  'PluginPage.card.udp-logger.desc': '对接 UDP 日志服务器',
-  'PluginPage.card.udp-logger.property.host': '日志服务器地址',
-  'PluginPage.card.udp-logger.property.port': '日志服务器端口',
-  'PluginPage.card.udp-logger.property.timeout': '超时时间',
-
-  'PluginPage.card.zipkin.desc': '对接 zipkin',
-  'PluginPage.card.zipkin.property.endpoint': 'endpoint',
-  'PluginPage.card.zipkin.property.endpoint.extra': '例如:http://127.0.0.1:9411/api/v2/spans',
-  'PluginPage.card.zipkin.property.sample_ratio': '采样率',
-  'PluginPage.card.zipkin.property.service_name': '服务名',
-  'PluginPage.card.zipkin.property.server_addr': '网关实例 IP',
-  'PluginPage.card.zipkin.property.server_addr.extra': '默认值是 Nginx 内置变量 server_addr',
-
-  'PluginPage.card.skywalking.desc': '对接 Apache Skywalking',
-  'PluginPage.card.skywalking.property.endpoint': 'endpoint',
-  'PluginPage.card.skywalking.property.endpoint.extra': '例如:http://127.0.0.1:12800',
-  'PluginPage.card.skywalking.property.sample_ratio': '采样率',
-  'PluginPage.card.skywalking.property.service_name': '服务名',
-
-  'PluginPage.card.serverless-pre-function.desc': '在指定阶段最开始的位置,运行指定的 Lua 函数',
-  'PluginPage.card.serverless-pre-function.property.phase': '运行阶段',
-  'PluginPage.card.serverless-pre-function.property.functions': '运行的函数集',
-
-  'PluginPage.card.serverless-post-function.desc': '在指定阶段最后的位置,运行指定的 Lua 函数',
-  'PluginPage.card.serverless-post-function.property.phase': '运行阶段',
-  'PluginPage.card.serverless-post-function.property.functions': '运行的函数集',
-
-  'PluginPage.card.basic-auth.desc': 'basic auth 插件',
-  'PluginPage.card.jwt-auth.desc': 'JWT 认证插件',
-  'PluginPage.card.key-auth.desc': 'key auth 插件',
-  'PluginPage.card.wolf-rbac.desc': '对接 wolf RBAC 服务',
-  'PluginPage.card.openid-connect.desc': 'Open ID Connect(OIDC) 插件提供对接外部认证服务的能力',
-
-  'PluginPage.card.redirect.desc': '重定向插件',
-  'PluginPage.card.proxy-rewrite.desc': 'proxy rewrite 代理改写插件,可以改写客户端请求',
-  'PluginPage.card.mqtt-proxy.desc':
-    'mqtt-proxy 插件可以帮助你根据 MQTT 的 client_id 实现动态负载均衡',
-  'PluginPage.card.grpc-transcoding.desc':
-    'gRPC 转换插件,实现 HTTP(s) -> APISIX -> gRPC server 的转换',
-  'PluginPage.card.batch-requests.desc':
-    'batch-requests 插件可以一次接受多个请求并以 http pipeline 的方式在网关发起多个 http 请求,合并结果后再返回客户端,这在客户端需要访问多个接口时可以显著地提升请求性能',
-
-  'PluginPage.card.node-status.desc': '节点状态',
-  'PluginPage.card.refer.documents':'请查阅官方文档',
-
-  'PluginPage.drawer.configure.plugin':'配置插件',
-  'PluginPage.drawer.disabled':'禁用',
-  'PluginPage.drawer.enable':'启用',
-  'PluginPage.drawer.cancel':'取消',
-  'PluginPage.drawer.confirm':'确认',
-  'PluginPage.drawer.is.enabled':'已启用',
-  'PluginPage.drawer.not.enabled':'未启用',
-};
\ No newline at end of file
diff --git a/src/components/PluginPage/service.ts b/src/components/PluginPage/service.ts
deleted file mode 100644
index 9315c63..0000000
--- a/src/components/PluginPage/service.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { request } from 'umi';
-
-import { JSONSchema7 } from 'json-schema';
-
-import { PLUGIN_MAPPER_SOURCE } from './data';
-
-export const fetchPluginList = () => request<string[]>('/plugins');
-
-export const getList = (plugins: PluginPage.PluginData) => {
-  const PLUGIN_BLOCK_LIST = Object.entries(PLUGIN_MAPPER_SOURCE)
-    .filter(([, value]) => value.hidden)
-    .flat()
-    .filter((item) => typeof item === 'string');
-
-  return fetchPluginList().then((data) => {
-    const names = data.filter((name) => !PLUGIN_BLOCK_LIST.includes(name));
-
-    const activeNameList = Object.keys(plugins);
-    const inactiveNameList = names.filter((name) => !activeNameList.includes(name));
-
-    return {
-      activeList: activeNameList.map((name) => ({ name, ...PLUGIN_MAPPER_SOURCE[name] })),
-      inactiveList: inactiveNameList.map((name) => ({ name, ...PLUGIN_MAPPER_SOURCE[name] })),
-    };
-  });
-};
-
-export const fetchPluginSchema = (name: string): Promise<JSONSchema7> =>
-  request(`/schema/plugins/${name}`);
diff --git a/src/components/PluginPage/typing.d.ts b/src/components/PluginPage/typing.d.ts
deleted file mode 100644
index bd3beb6..0000000
--- a/src/components/PluginPage/typing.d.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-declare namespace PluginPage {
-  type PluginCategory = 'Security' | 'Limit' | 'Log' | 'Metric' | 'Other';
-
-  type PluginMapperItem = {
-    category: PluginCategory;
-    hidden?: boolean;
-  };
-
-  interface PluginProps extends PluginMapperItem {
-    name: string;
-  }
-
-  type PluginData = { [name: string]: any };
-}
diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts
index 1d34eac..6ea6069 100644
--- a/src/locales/en-US.ts
+++ b/src/locales/en-US.ts
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { PluginPageEnUS } from '@/components/PluginPage';
 import { ActionBarEnUS } from '@/components/ActionBar';
 
 import component from './en-US/component';
@@ -36,6 +35,5 @@ export default {
   ...settings,
   ...pwa,
   ...component,
-  ...PluginPageEnUS,
   ...ActionBarEnUS,
 };
diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts
index b8cbae9..3eb93eb 100644
--- a/src/locales/zh-CN.ts
+++ b/src/locales/zh-CN.ts
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import { PluginPageZhCN } from '@/components/PluginPage';
 import { ActionBarZhCN } from '@/components/ActionBar';
 
 import component from './zh-CN/component';
@@ -36,6 +35,5 @@ export default {
   ...settings,
   ...pwa,
   ...component,
-  ...PluginPageZhCN,
   ...ActionBarZhCN,
 };
diff --git a/src/pages/Consumer/Create.tsx b/src/pages/Consumer/Create.tsx
index 28ccd2f..83da1ee 100644
--- a/src/pages/Consumer/Create.tsx
+++ b/src/pages/Consumer/Create.tsx
@@ -18,10 +18,9 @@ import React, { useState, useEffect } from 'react';
 import { PageContainer } from '@ant-design/pro-layout';
 import { Card, Steps, notification, Form } from 'antd';
 import { history, useIntl } from 'umi';
+import { PluginPage, PLUGIN_MAPPER_SOURCE, PluginPageType } from '@api7-dashboard/plugin';
 
 import ActionBar from '@/components/ActionBar';
-import PluginPage from '@/components/PluginPage';
-import { PLUGIN_MAPPER_SOURCE } from '@/components/PluginPage/data';
 
 import Step1 from './components/Step1';
 import Preview from './components/Preview';
@@ -29,7 +28,7 @@ import { fetchItem, create, update } from './service';
 
 const Page: React.FC = (props) => {
   const [step, setStep] = useState(1);
-  const [plugins, setPlugins] = useState<PluginPage.PluginData>({});
+  const [plugins, setPlugins] = useState<PluginPageType.PluginData>({});
   const [form1] = Form.useForm();
   const { formatMessage } = useIntl();
 
diff --git a/src/pages/Consumer/components/Preview.tsx b/src/pages/Consumer/components/Preview.tsx
index e580bd7..a894f0e 100644
--- a/src/pages/Consumer/components/Preview.tsx
+++ b/src/pages/Consumer/components/Preview.tsx
@@ -16,14 +16,13 @@
  */
 import React from 'react';
 import { FormInstance } from 'antd/lib/form';
-
-import PluginPage from '@/components/PluginPage';
+import { PluginPage, PluginPageType } from '@api7-dashboard/plugin';
 
 import Step1 from './Step1';
 
 type Props = {
   form1: FormInstance;
-  plugins: PluginPage.PluginData;
+  plugins: PluginPageType.PluginData;
 };
 
 const Page: React.FC<Props> = ({ form1, plugins }) => {
diff --git a/src/pages/Route/components/CreateStep4/CreateStep4.tsx b/src/pages/Route/components/CreateStep4/CreateStep4.tsx
index a4b0f2c..c3fa210 100644
--- a/src/pages/Route/components/CreateStep4/CreateStep4.tsx
+++ b/src/pages/Route/components/CreateStep4/CreateStep4.tsx
@@ -17,8 +17,7 @@
 import React from 'react';
 import { FormInstance } from 'antd/lib/form';
 import { useIntl } from 'umi';
-
-import PluginPage from '@/components/PluginPage';
+import { PluginPage } from '@api7-dashboard/plugin';
 
 import Step1 from '../Step1';
 import Step2 from '../Step2';
@@ -34,7 +33,6 @@ const style = {
 };
 
 const CreateStep4: React.FC<Props> = ({ form1, form2, redirect, ...rest }) => {
-
   const { formatMessage } = useIntl();
 
   return (
diff --git a/src/pages/Route/components/Step1/MatchingRulesView.tsx b/src/pages/Route/components/Step1/MatchingRulesView.tsx
index be403da..ed42f45 100644
--- a/src/pages/Route/components/Step1/MatchingRulesView.tsx
+++ b/src/pages/Route/components/Step1/MatchingRulesView.tsx
@@ -17,8 +17,7 @@
 import React, { useState } from 'react';
 import { Button, Table, Modal, Form, Select, Input, Space } from 'antd';
 import { useIntl } from 'umi';
-
-import PanelSection from '@/components/PanelSection';
+import { PanelSection } from '@api7-dashboard/ui';
 
 interface Props extends RouteModule.Data {}
 
diff --git a/src/pages/Route/components/Step1/MetaView.tsx b/src/pages/Route/components/Step1/MetaView.tsx
index 10fb203..b04a5ac 100644
--- a/src/pages/Route/components/Step1/MetaView.tsx
+++ b/src/pages/Route/components/Step1/MetaView.tsx
@@ -18,8 +18,7 @@ import React from 'react';
 import Form from 'antd/es/form';
 import { Input } from 'antd';
 import { useIntl } from 'umi';
-
-import PanelSection from '@/components/PanelSection';
+import { PanelSection } from '@api7-dashboard/ui';
 
 interface Props extends RouteModule.Data {}
 
@@ -39,10 +38,16 @@ const MetaView: React.FC<Props> = ({ disabled }) => {
         ]}
         extra={formatMessage({ id: 'rotue.meta.api.rule' })}
       >
-        <Input placeholder={formatMessage({ id: 'route.meta.input.api.name' })} disabled={disabled} />
+        <Input
+          placeholder={formatMessage({ id: 'route.meta.input.api.name' })}
+          disabled={disabled}
+        />
       </Form.Item>
       <Form.Item label={formatMessage({ id: 'route.meta.description' })} name="desc">
-        <Input.TextArea placeholder={formatMessage({ id: 'route.meta.description.rule' })} disabled={disabled} />
+        <Input.TextArea
+          placeholder={formatMessage({ id: 'route.meta.description.rule' })}
+          disabled={disabled}
+        />
       </Form.Item>
     </PanelSection>
   );
diff --git a/src/pages/Route/components/Step1/RequestConfigView.tsx b/src/pages/Route/components/Step1/RequestConfigView.tsx
index 60bd885..53e4013 100644
--- a/src/pages/Route/components/Step1/RequestConfigView.tsx
+++ b/src/pages/Route/components/Step1/RequestConfigView.tsx
@@ -20,6 +20,7 @@ import { Checkbox, Button, Input, Switch, Select, Row, Col } from 'antd';
 import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons';
 import { CheckboxValueType } from 'antd/lib/checkbox/Group';
 import { useIntl } from 'umi';
+import { PanelSection } from '@api7-dashboard/ui';
 
 import {
   HTTP_METHOD_OPTION_LIST,
@@ -27,8 +28,6 @@ import {
   FORM_ITEM_WITHOUT_LABEL,
 } from '@/pages/Route/constants';
 
-import PanelSection from '@/components/PanelSection';
-
 interface Props extends RouteModule.Data {}
 
 const RequestConfigView: React.FC<Props> = ({ data, disabled, onChange }) => {
diff --git a/src/pages/Route/components/Step2/HttpHeaderRewriteView.tsx b/src/pages/Route/components/Step2/HttpHeaderRewriteView.tsx
index 665bb21..543db05 100644
--- a/src/pages/Route/components/Step2/HttpHeaderRewriteView.tsx
+++ b/src/pages/Route/components/Step2/HttpHeaderRewriteView.tsx
@@ -18,8 +18,7 @@ import React, { useState } from 'react';
 import Form from 'antd/es/form';
 import { Button, Table, Space, Modal, Input, Select } from 'antd';
 import { useIntl } from 'umi';
-
-import PanelSection from '@/components/PanelSection';
+import { PanelSection } from '@api7-dashboard/ui';
 
 interface Props extends RouteModule.Data {}
 
diff --git a/src/pages/Route/components/Step2/RequestRewriteView.tsx b/src/pages/Route/components/Step2/RequestRewriteView.tsx
index da56ef1..12ad7af 100644
--- a/src/pages/Route/components/Step2/RequestRewriteView.tsx
+++ b/src/pages/Route/components/Step2/RequestRewriteView.tsx
@@ -20,6 +20,7 @@ import Radio from 'antd/lib/radio';
 import { Input, Row, Col, InputNumber, Button, Select } from 'antd';
 import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons';
 import { useIntl } from 'umi';
+import { PanelSection } from '@api7-dashboard/ui';
 
 import {
   FORM_ITEM_LAYOUT,
@@ -27,7 +28,6 @@ import {
   HASH_KEY_LIST,
   HASH_ON_LIST,
 } from '@/pages/Route/constants';
-import PanelSection from '@/components/PanelSection';
 import styles from '../../Create.less';
 import { fetchUpstreamList } from '../../service';
 
diff --git a/yarn.lock b/yarn.lock
index d29ca51..254ea37 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -187,20 +187,20 @@
     lodash "^4.17.15"
     resize-observer-polyfill "^1.5.0"
 
-"@api7-dashboard/plugin@^1.0.2":
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/@api7-dashboard/plugin/-/plugin-1.0.2.tgz#b7f9d2dbb4f4ab17a9cbd66e484578287a0adb2d"
-  integrity sha512-Q7bbZ6Wh3b7SbdFEDv9aKqbZMeuYootufeP1d12rNzTT7T2JLePFEyjt8oeVbN2zXl7IvJzdYF+MbgzRTD9YYg==
+"@api7-dashboard/plugin@^1.0.3":
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/@api7-dashboard/plugin/-/plugin-1.0.3.tgz#de51d10abdb5e64eede1699586fca9b532c46c00"
+  integrity sha512-jSl/r0Rjo4ePIPUZfTvRqFxzsVUsfn9Kyx/9PdvxLxLDR2DYEsajfNBRU+s7mUuwzRJ9djkMIqeA+FnFxTHLyQ==
   dependencies:
     "@rjsf/antd" "^2.3.0"
     "@rjsf/core" "^2.3.0"
     json-schema "^0.2.5"
     set-value "^3.0.2"
 
-"@api7-dashboard/pluginchart@^1.0.8":
-  version "1.0.8"
-  resolved "https://registry.npm.taobao.org/@api7-dashboard/pluginchart/download/@api7-dashboard/pluginchart-1.0.8.tgz?cache=0&sync_timestamp=1599205139159&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40api7-dashboard%2Fpluginchart%2Fdownload%2F%40api7-dashboard%2Fpluginchart-1.0.8.tgz#4412eb632193f7e7c175b5d84b1f0d0c2d92de25"
-  integrity sha1-RBLrYyGT9+fBdbXYSx8NDC2S3iU=
+"@api7-dashboard/pluginchart@^1.0.9":
+  version "1.0.9"
+  resolved "https://registry.yarnpkg.com/@api7-dashboard/pluginchart/-/pluginchart-1.0.9.tgz#306808dbe08f46ae02eca976d6495046830f8d3d"
+  integrity sha512-YCBQrwI/K2K2BFXWGy69BNbPiH+sxac0LpYDtiqhJFEGVZq1kR/OLh3eHeCRObpBuBGmGc+Bw3DGsrYd3v3c1Q==
   dependencies:
     "@ant-design/icons" "^4.2.2"
     "@mrblenny/react-flow-chart" "^0.0.14"