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 f1b8f0c feat: added types for Plugins (#1736)
f1b8f0c is described below
commit f1b8f0c087187d511bce0d217ce72901e3c6a6a0
Author: 琚致远 <[email protected]>
AuthorDate: Thu Apr 15 17:29:00 2021 +0800
feat: added types for Plugins (#1736)
---
.../create-edit-delete-plugin-template.spec.js | 6 +-
...eate-route-with-limit-count-plugin-form.spec.js | 2 +
web/src/components/Plugin/PluginPage.tsx | 33 +++--
web/src/components/Plugin/data.tsx | 164 ++++++++++++++++++++-
web/src/components/Plugin/locales/en-US.ts | 8 +
web/src/components/Plugin/locales/zh-CN.ts | 8 +
web/src/components/Plugin/service.ts | 16 +-
web/src/components/Plugin/typing.d.ts | 3 +-
web/src/pages/Plugin/locales/en-US.ts | 2 +-
web/src/pages/Plugin/locales/zh-CN.ts | 2 +-
10 files changed, 222 insertions(+), 22 deletions(-)
diff --git
a/web/cypress/integration/pluginTemplate/create-edit-delete-plugin-template.spec.js
b/web/cypress/integration/pluginTemplate/create-edit-delete-plugin-template.spec.js
index ea0a4dd..cd3a2a4 100644
---
a/web/cypress/integration/pluginTemplate/create-edit-delete-plugin-template.spec.js
+++
b/web/cypress/integration/pluginTemplate/create-edit-delete-plugin-template.spec.js
@@ -40,8 +40,10 @@ context('Create Configure and Delete PluginTemplate', () => {
// should not see proxy-rewrite plugin in the step2
cy.contains('proxy-rewrite').should('not.exist');
- cy.contains('Enable').click({
- force: true
+ cy.contains(this.domSelector.pluginCard, 'basic-auth').within(() => {
+ cy.contains('Enable').click({
+ force: true,
+ });
});
cy.focused(this.domSelector.drawer).should('exist');
diff --git
a/web/cypress/integration/route/create-route-with-limit-count-plugin-form.spec.js
b/web/cypress/integration/route/create-route-with-limit-count-plugin-form.spec.js
index 7992f2c..f9db28b 100644
---
a/web/cypress/integration/route/create-route-with-limit-count-plugin-form.spec.js
+++
b/web/cypress/integration/route/create-route-with-limit-count-plugin-form.spec.js
@@ -51,6 +51,8 @@ context('Create and delete route with limit-count form', ()
=> {
cy.contains('Next').click();
cy.get(this.domSelector.nodes_0_host).type('127.0.0.1');
+ cy.get(this.domSelector.nodes_0_port).clear().type(this.data.port);
+ cy.get(this.domSelector.nodes_0_weight).clear().type(this.data.weight);
cy.contains('Next').click();
// config limit-count form with local policy
diff --git a/web/src/components/Plugin/PluginPage.tsx
b/web/src/components/Plugin/PluginPage.tsx
index fa30a73..61e9bee 100644
--- a/web/src/components/Plugin/PluginPage.tsx
+++ b/web/src/components/Plugin/PluginPage.tsx
@@ -67,7 +67,6 @@ const PluginPage: React.FC<Props> = ({
const [typeList, setTypeList] = useState<string[]>([]);
const [plugins, setPlugins] = useState({});
- const firstUpperCase = ([first, ...rest]: string) => first.toUpperCase() +
rest.join('');
useEffect(() => {
setPlugins(initialData);
fetchList().then((data) => {
@@ -80,11 +79,11 @@ const PluginPage: React.FC<Props> = ({
setPluginList(filteredData);
const categoryList: string[] = [];
data.forEach((item) => {
- if (!categoryList.includes(firstUpperCase(item.type))) {
- categoryList.push(firstUpperCase(item.type));
+ if (!categoryList.includes(item.type)) {
+ categoryList.push(item.type);
}
});
- setTypeList(categoryList.sort());
+ setTypeList(categoryList);
});
fetchPluginTemplateList().then((data) => {
setPluginTemplateList(data);
@@ -96,20 +95,24 @@ const PluginPage: React.FC<Props> = ({
<>
<style>
{`
- .ant-card-body .icon {
- width: 5em;
- height: 5em;
- margin-right: 0;
- overflow: hidden;
- vertical-align: -0.15em;
- fill: currentColor;
- }`}
+ .ant-card-body .icon {
+ width: 5em;
+ height: 5em;
+ margin-right: 0;
+ overflow: hidden;
+ vertical-align: -0.15em;
+ fill: currentColor;
+ }
+ .ant-card-head {
+ padding: 0;
+ }
+ `}
</style>
<Sider theme="light">
<Anchor offsetTop={150}>
{typeList.map((typeItem) => {
return (
- <Anchor.Link href={`#plugin-category-${typeItem}`}
title={typeItem} key={typeItem} />
+ <Anchor.Link href={`#plugin-category-${typeItem}`}
title={formatMessage({ id: `component.plugin.${typeItem}` })} key={typeItem} />
);
})}
</Anchor>
@@ -166,13 +169,13 @@ const PluginPage: React.FC<Props> = ({
{typeList.map((typeItem) => {
return (
<PanelSection
- title={typeItem}
+ title={formatMessage({ id: `component.plugin.${typeItem}` })}
key={typeItem}
style={PanelSectionStyle}
id={`plugin-category-${typeItem}`}
>
{orderBy(
- pluginList.filter((item) => item.type ===
typeItem.toLowerCase()),
+ pluginList.filter((item) => item.type ===
typeItem.toLowerCase() && !item.hidden),
'name',
'asc',
).map((item) => (
diff --git a/web/src/components/Plugin/data.tsx
b/web/src/components/Plugin/data.tsx
index dc6db0c..df119c1 100644
--- a/web/src/components/Plugin/data.tsx
+++ b/web/src/components/Plugin/data.tsx
@@ -30,5 +30,167 @@ export const PLUGIN_ICON_LIST: Record<string, any> = {
// This list is used to filter out plugins that cannot be displayed in the
plugins list.
export const PLUGIN_FILTER_LIST: Record<string, { list:
PluginComponent.ReferPage[] }> = {
redirect: { list: ['route'] }, // Filter out the redirect plugin on the
route page.
- 'proxy-rewrite': { list: ['route']},
+ 'proxy-rewrite': { list: ['route'] },
};
+
+export enum PluginType {
+ authentication = "authentication",
+ security = "security",
+ traffic = "traffic",
+ serverless = "serverless",
+ observability = "observability",
+ logging = "logging",
+ other = "other"
+}
+
+/**
+ * Plugin List that contains type field
+*/
+export const PLUGIN_LIST = {
+ "hmac-auth": {
+ type: PluginType.authentication
+ },
+ "serverless-post-function": {
+ type: PluginType.serverless
+ },
+ "mqtt-proxy": {
+ type: PluginType.other,
+ hidden: true
+ },
+ "response-rewrite": {
+ type: PluginType.other
+ },
+ "basic-auth": {
+ type: PluginType.authentication
+ },
+ "error-log-logger": {
+ type: PluginType.logging
+ },
+ "fault-injection": {
+ type: PluginType.security
+ },
+ "limit-count": {
+ type: PluginType.traffic
+ },
+ "prometheus": {
+ type: PluginType.observability
+ },
+ "proxy-rewrite": {
+ type: PluginType.other
+ },
+ "syslog": {
+ type: PluginType.logging
+ },
+ "traffic-split": {
+ type: PluginType.traffic
+ },
+ "jwt-auth": {
+ type: PluginType.authentication
+ },
+ "kafka-logger": {
+ type: PluginType.logging
+ },
+ "limit-conn": {
+ type: PluginType.traffic
+ },
+ "udp-logger": {
+ type: PluginType.logging
+ },
+ "zipkin": {
+ type: PluginType.observability
+ },
+ "echo": {
+ type: PluginType.other,
+ hidden: true
+ },
+ "log-rotate": {
+ type: PluginType.logging,
+ hidden: true
+ },
+ "serverless-pre-function": {
+ type: PluginType.serverless
+ },
+ "dubbo-proxy": {
+ type: PluginType.other,
+ hidden: true
+ },
+ "node-status": {
+ type: PluginType.other,
+ hidden: true
+ },
+ "referer-restriction": {
+ type: PluginType.security
+ },
+ "api-breaker": {
+ type: PluginType.security,
+ },
+ "consumer-restriction": {
+ type: PluginType.security
+ },
+ "cors": {
+ type: PluginType.security
+ },
+ "limit-req": {
+ type: PluginType.traffic
+ },
+ "proxy-mirror": {
+ type: PluginType.other
+ },
+ "request-validation": {
+ type: PluginType.security
+ },
+ "example-plugin": {
+ type: PluginType.other,
+ hidden: true
+ },
+ "ip-restriction": {
+ type: PluginType.security
+ },
+ "key-auth": {
+ type: PluginType.authentication
+ },
+ "proxy-cache": {
+ type: PluginType.other
+ },
+ "redirect": {
+ type: PluginType.other,
+ hidden: true
+ },
+ "request-id": {
+ type: PluginType.observability
+ },
+ "skywalking": {
+ type: PluginType.observability
+ },
+ "batch-requests": {
+ type: PluginType.other
+ },
+ "http-logger": {
+ type: PluginType.logging
+ },
+ "openid-connect": {
+ type: PluginType.authentication
+ },
+ "sls-logger": {
+ type: PluginType.logging
+ },
+ "tcp-logger": {
+ type: PluginType.logging
+ },
+ "uri-blocker": {
+ type: PluginType.security
+ },
+ "wolf-rbac": {
+ type: PluginType.other
+ },
+ "authz-keycloak": {
+ type: PluginType.authentication
+ },
+ "grpc-transcode": {
+ type: PluginType.other
+ },
+ "server-info": {
+ type: PluginType.other,
+ hidden: true
+ }
+}
diff --git a/web/src/components/Plugin/locales/en-US.ts
b/web/src/components/Plugin/locales/en-US.ts
index 10363bd..26fa357 100644
--- a/web/src/components/Plugin/locales/en-US.ts
+++ b/web/src/components/Plugin/locales/en-US.ts
@@ -21,6 +21,14 @@ export default {
'component.step.select.pluginTemplate.select.option': 'Custom',
'component.plugin.pluginTemplate.tip1': '1. When a route already have
plugins field configured, the plugins in the plugin template will be merged
into it.',
'component.plugin.pluginTemplate.tip2': '2. The same plugin in the plugin
template will override one in the plugins',
+ 'component.plugin.authentication': 'Authentication',
+ 'component.plugin.security': 'Security',
+ 'component.plugin.traffic': 'Traffic Control',
+ 'component.plugin.serverless': 'Serverless',
+ 'component.plugin.observability': 'Tracing & Metrics & Logging',
+ 'component.plugin.logging': 'Logging',
+ 'component.plugin.other': 'Other',
+
// cors
'component.pluginForm.cors.allow_origins.tooltip': 'Which Origins is allowed
to enable CORS, format as:scheme://host:port, for example:
https://somehost.com:8081. Multiple origin use , to split. When
allow_credential is false, you can use * to indicate allow any origin. you also
can allow all any origins forcefully using ** even already enable
allow_credential, but it will bring some security risks.',
'component.pluginForm.cors.allow_origins.extra': 'For example:
https://somehost.com:8081',
diff --git a/web/src/components/Plugin/locales/zh-CN.ts
b/web/src/components/Plugin/locales/zh-CN.ts
index 6d25eb4..b88f6e8 100644
--- a/web/src/components/Plugin/locales/zh-CN.ts
+++ b/web/src/components/Plugin/locales/zh-CN.ts
@@ -21,6 +21,14 @@ export default {
'component.step.select.pluginTemplate.select.option': '手动配置',
'component.plugin.pluginTemplate.tip1': '1. 若路由已配置插件,则插件模板数据将与已配置的插件数据合并。',
'component.plugin.pluginTemplate.tip2': '2. 插件模板相同的插件会覆盖掉原有的插件。',
+ 'component.plugin.authentication': '身份验证',
+ 'component.plugin.security': '安全防护',
+ 'component.plugin.traffic': '流量控制',
+ 'component.plugin.serverless': '无服务器架构',
+ 'component.plugin.observability': '可观测性',
+ 'component.plugin.logging': '日志记录',
+ 'component.plugin.other': '其它',
+
// cors
'component.pluginForm.cors.allow_origins.tooltip': '允许跨域访问的
Origin,格式如:scheme://host:port,比如: https://somehost.com:8081 。多个值使用 ,
分割,allow_credential 为 false 时可以使用 * 来表示所有 Origin 均允许通过。你也可以在启用了
allow_credential 后使用 ** 强制允许所有 Origin 都通过,但请注意这样存在安全隐患。',
'component.pluginForm.cors.allow_origins.extra': '例如:
https://somehost.com:8081',
diff --git a/web/src/components/Plugin/service.ts
b/web/src/components/Plugin/service.ts
index 5a1b427..89c7fee 100644
--- a/web/src/components/Plugin/service.ts
+++ b/web/src/components/Plugin/service.ts
@@ -17,9 +17,23 @@
import { omit } from 'lodash';
import { request } from 'umi';
+import { PLUGIN_LIST, PluginType } from './data';
+
export const fetchList = () => {
return request<Res<PluginComponent.Meta[]>>('/plugins?all=true').then((data)
=> {
- return data.data;
+ const typedData = data.data.map(item => ({
+ ...item,
+ type: PLUGIN_LIST[item.name]?.type || "other",
+ hidden: PLUGIN_LIST[item.name]?.hidden || false
+ }));
+
+ let finalList: PluginComponent.Meta[] = []
+
+ Object.values(PluginType).forEach(type => {
+ finalList = finalList.concat(typedData.filter(item => item.type ===
type))
+ })
+
+ return finalList
});
};
diff --git a/web/src/components/Plugin/typing.d.ts
b/web/src/components/Plugin/typing.d.ts
index c92b882..0fe2052 100644
--- a/web/src/components/Plugin/typing.d.ts
+++ b/web/src/components/Plugin/typing.d.ts
@@ -26,9 +26,10 @@ declare namespace PluginComponent {
type: string;
version: number;
consumer_schema?: Record<string, any>;
+ hidden?: boolean;
};
type ReferPage = '' | 'route' | 'consumer' | 'service' | 'plugin';
- type CodeMirrorMode = 'JSON' | 'YAML'| 'Form';
+ type CodeMirrorMode = 'JSON' | 'YAML' | 'Form';
}
diff --git a/web/src/pages/Plugin/locales/en-US.ts
b/web/src/pages/Plugin/locales/en-US.ts
index 72ad832..16e45f8 100644
--- a/web/src/pages/Plugin/locales/en-US.ts
+++ b/web/src/pages/Plugin/locales/en-US.ts
@@ -18,5 +18,5 @@ export default {
'page.plugin.drawer.popconfirm.title.delete': 'Are you sure to delete this
item?',
'page.plugin.list': 'Plugin List',
'page.plugin.list.enabled': 'List of enabled plugins',
- 'page.plugin.market.config': 'Configure Plugin',
+ 'page.plugin.market.config': 'Global Plugin List',
};
diff --git a/web/src/pages/Plugin/locales/zh-CN.ts
b/web/src/pages/Plugin/locales/zh-CN.ts
index 2ceb854..9915323 100644
--- a/web/src/pages/Plugin/locales/zh-CN.ts
+++ b/web/src/pages/Plugin/locales/zh-CN.ts
@@ -18,5 +18,5 @@ export default {
'page.plugin.drawer.popconfirm.title.delete': '确定删除该插件吗?',
'page.plugin.list': '插件列表',
'page.plugin.list.enabled': '已启用插件的列表',
- 'page.plugin.market.config': '配置列表',
+ 'page.plugin.market.config': '全局插件列表',
};