This is an automated email from the ASF dual-hosted git repository.
xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new 794dde9d [Bugfix] namespace plugin batch enable (#512)
794dde9d is described below
commit 794dde9d65583b57b94d7b7796a12f1372bbff8c
Author: aias00 <[email protected]>
AuthorDate: Tue Dec 3 11:04:23 2024 +0800
[Bugfix] namespace plugin batch enable (#512)
* fix namespace plugin batch enable
* fix get alert receviers
* fix namespace plugin get selector
* fix ns plugin selector bug
* fix namespace detail restful
* fix namespace plugin restful
* fix data permission ns bug
* support copy selector from other ns
* support rule copy from other ns
---
src/models/global.js | 22 +++++++++++++
src/routes/Plugin/Common/RuleCopy.js | 49 +++++++++++++++++++++++++--
src/routes/Plugin/Common/SelectorCopy.js | 52 ++++++++++++++++++++++++++---
src/routes/Plugin/Common/index.js | 21 +++++++-----
src/routes/System/Alert/index.js | 6 ++--
src/routes/System/NamespacePlugin/index.js | 6 ++--
src/routes/System/User/DataPermModal.js | 53 +++++++++++++++++++-----------
src/services/api.js | 26 +++++++++------
8 files changed, 183 insertions(+), 52 deletions(-)
diff --git a/src/models/global.js b/src/models/global.js
index 64ca7cb6..0d2357d7 100644
--- a/src/models/global.js
+++ b/src/models/global.js
@@ -86,6 +86,28 @@ export default {
});
}
},
+ *fetchPluginsByNamespace({ payload }, { call, put }) {
+ const { callback, namespaceId } = payload ?? {};
+ const params = {
+ namespaceId,
+ currentPage: 1,
+ pageSize: 50,
+ };
+ const json = yield call(getPluginsByNamespace, params);
+ if (json.code === 200) {
+ let { dataList } = json.data;
+
+ if (callback) {
+ callback(dataList);
+ }
+ yield put({
+ type: "savePlugins",
+ payload: {
+ dataList,
+ },
+ });
+ }
+ },
*asyncPlugin(params, { call }) {
const { payload } = params;
const json = yield call(asyncByPluginAndNamespace, payload);
diff --git a/src/routes/Plugin/Common/RuleCopy.js
b/src/routes/Plugin/Common/RuleCopy.js
index d79b5ed6..27417207 100644
--- a/src/routes/Plugin/Common/RuleCopy.js
+++ b/src/routes/Plugin/Common/RuleCopy.js
@@ -16,7 +16,7 @@
*/
import React, { Component } from "react";
-import { Modal, TreeSelect } from "antd";
+import { Modal, TreeSelect, Dropdown, Menu, Button, Icon } from "antd";
import { connect } from "dva";
import {
getPluginDropDownListByNamespace,
@@ -25,9 +25,11 @@ import {
findRule,
} from "../../../services/api";
import { getIntlContent } from "../../../utils/IntlUtils";
+import { defaultNamespaceId } from "../../../components/_utils/utils";
@connect(({ global }) => ({
currentNamespaceId: global.currentNamespaceId,
+ namespaces: global.namespaces,
}))
class RuleCopy extends Component {
constructor(props) {
@@ -36,6 +38,7 @@ class RuleCopy extends Component {
ruleTree: [],
value: undefined,
loading: false,
+ currentNamespaceId: defaultNamespaceId,
};
}
@@ -43,6 +46,12 @@ class RuleCopy extends Component {
this.getAllRule();
}
+ handleNamespacesValueChange = (value) => {
+ this.setState({ currentNamespaceId: value.key }, () => {
+ this.getAllRule();
+ });
+ };
+
getAllRule = async () => {
const { currentNamespaceId } = this.props;
const { code: pluginCode, data: pluginList = [] } =
@@ -133,8 +142,8 @@ class RuleCopy extends Component {
};
render() {
- const { visible = false } = this.props;
- const { ruleTree, value, loading } = this.state;
+ const { visible = false, namespaces } = this.props;
+ const { ruleTree, value, loading, currentNamespaceId } = this.state;
return (
<Modal
visible={visible}
@@ -144,6 +153,40 @@ class RuleCopy extends Component {
onOk={this.handleOk}
confirmLoading={loading}
>
+ <Dropdown
+ placement="bottomCenter"
+ overlay={
+ <Menu onClick={this.handleNamespacesValueChange}>
+ {namespaces.map((namespace) => {
+ let isCurrentNamespace =
+ currentNamespaceId === namespace.namespaceId;
+ return (
+ <Menu.Item
+ key={namespace.namespaceId}
+ disabled={isCurrentNamespace}
+ >
+ <span>{namespace.name}</span>
+ </Menu.Item>
+ );
+ })}
+ </Menu>
+ }
+ >
+ <Button>
+ <a
+ className="ant-dropdown-link"
+ style={{ fontWeight: "bold" }}
+ onClick={(e) => e.preventDefault()}
+ >
+ {`${getIntlContent("SHENYU.SYSTEM.NAMESPACE")} / ${
+ namespaces.find(
+ (namespace) => currentNamespaceId === namespace.namespaceId,
+ )?.name
+ } `}
+ </a>
+ <Icon type="down" />
+ </Button>
+ </Dropdown>
<TreeSelect
style={{ width: "100%" }}
showSearch
diff --git a/src/routes/Plugin/Common/SelectorCopy.js
b/src/routes/Plugin/Common/SelectorCopy.js
index 959efa91..9ca62fa0 100644
--- a/src/routes/Plugin/Common/SelectorCopy.js
+++ b/src/routes/Plugin/Common/SelectorCopy.js
@@ -16,7 +16,7 @@
*/
import React, { Component } from "react";
-import { Modal, TreeSelect } from "antd";
+import { Modal, TreeSelect, Dropdown, Menu, Button, Icon } from "antd";
import { connect } from "dva";
import {
getPluginDropDownListByNamespace,
@@ -24,9 +24,10 @@ import {
findSelector,
} from "../../../services/api";
import { getIntlContent } from "../../../utils/IntlUtils";
+import { defaultNamespaceId } from "../../../components/_utils/utils";
@connect(({ global }) => ({
- currentNamespaceId: global.currentNamespaceId,
+ namespaces: global.namespaces,
}))
class SelectorCopy extends Component {
constructor(props) {
@@ -35,6 +36,7 @@ class SelectorCopy extends Component {
selectorTree: [],
value: undefined,
loading: false,
+ currentNamespaceId: defaultNamespaceId,
};
}
@@ -42,8 +44,14 @@ class SelectorCopy extends Component {
this.getAllSelectors();
}
+ handleNamespacesValueChange = (value) => {
+ this.setState({ currentNamespaceId: value.key }, () => {
+ this.getAllSelectors();
+ });
+ };
+
getAllSelectors = async () => {
- const { currentNamespaceId } = this.props;
+ const { currentNamespaceId } = this.state;
const { code: pluginCode, data: pluginList = [] } =
await getPluginDropDownListByNamespace({
namespace: currentNamespaceId,
@@ -113,8 +121,8 @@ class SelectorCopy extends Component {
};
render() {
- const { visible = false } = this.props;
- const { selectorTree, value, loading } = this.state;
+ const { visible = false, namespaces } = this.props;
+ const { selectorTree, value, loading, currentNamespaceId } = this.state;
return (
<Modal
visible={visible}
@@ -124,6 +132,40 @@ class SelectorCopy extends Component {
onOk={this.handleOk}
confirmLoading={loading}
>
+ <Dropdown
+ placement="bottomCenter"
+ overlay={
+ <Menu onClick={this.handleNamespacesValueChange}>
+ {namespaces.map((namespace) => {
+ let isCurrentNamespace =
+ currentNamespaceId === namespace.namespaceId;
+ return (
+ <Menu.Item
+ key={namespace.namespaceId}
+ disabled={isCurrentNamespace}
+ >
+ <span>{namespace.name}</span>
+ </Menu.Item>
+ );
+ })}
+ </Menu>
+ }
+ >
+ <Button>
+ <a
+ className="ant-dropdown-link"
+ style={{ fontWeight: "bold" }}
+ onClick={(e) => e.preventDefault()}
+ >
+ {`${getIntlContent("SHENYU.SYSTEM.NAMESPACE")} / ${
+ namespaces.find(
+ (namespace) => currentNamespaceId === namespace.namespaceId,
+ )?.name
+ } `}
+ </a>
+ <Icon type="down" />
+ </Button>
+ </Dropdown>
<TreeSelect
style={{ width: "100%" }}
showSearch
diff --git a/src/routes/Plugin/Common/index.js
b/src/routes/Plugin/Common/index.js
index 37b85ecb..a7d351e0 100755
--- a/src/routes/Plugin/Common/index.js
+++ b/src/routes/Plugin/Common/index.js
@@ -123,7 +123,7 @@ export default class Common extends Component {
const { selectorName } = this.state;
let name = this.props.match.params ? this.props.match.params.id : "";
const tempPlugin = this.getPlugin(plugins, name);
- const tempPluginId = tempPlugin?.id;
+ const tempPluginId = tempPlugin?.pluginId;
const enabled = tempPlugin?.enabled ?? false;
this.setState({ pluginId: tempPluginId, isPluginEnabled: enabled });
dispatch({
@@ -168,7 +168,7 @@ export default class Common extends Component {
getPluginId = (plugins, name) => {
let plugin = this.getPlugin(plugins, name);
if (plugin) {
- return plugin.id;
+ return plugin.pluginId;
} else {
return "";
}
@@ -210,7 +210,7 @@ export default class Common extends Component {
const { dispatch, plugins, currentNamespaceId } = this.props;
let name = this.props.match.params ? this.props.match.params.id : "";
const plugin = this.getPlugin(plugins, name);
- const { id: pluginId, config } = plugin;
+ const { pluginId, config } = plugin;
const multiSelectorHandle =
this.getPluginConfigField(config, "multiSelectorHandle") === "1";
const isDiscovery = this.isDiscovery(pluginId);
@@ -379,7 +379,7 @@ export default class Common extends Component {
const plugin = this.getPlugin(plugins, pluginName);
const enabled = !this.state.isPluginEnabled;
updateNamespacePluginsEnabledByNamespace({
- list: [plugin.id],
+ list: [plugin.pluginId],
namespaceId: this.props.currentNamespaceId,
enabled,
dispatch,
@@ -398,7 +398,7 @@ export default class Common extends Component {
: "";
const plugin = this.getPlugin(plugins, pluginName);
getUpdateModal({
- pluginId: plugin.id,
+ pluginId: plugin.pluginId,
dispatch,
callback: (popup) => {
this.setState({ popup });
@@ -504,7 +504,7 @@ export default class Common extends Component {
const { selectorPage, selectorPageSize } = this.state;
let name = this.props.match.params ? this.props.match.params.id : "";
const plugin = this.getPlugin(plugins, name);
- const { id: pluginId, config } = plugin;
+ const { pluginId, config } = plugin;
const multiSelectorHandle =
this.getPluginConfigField(config, "multiSelectorHandle") === "1";
const isDiscovery = this.isDiscovery(pluginId);
@@ -670,7 +670,7 @@ export default class Common extends Component {
const { selectorPage, selectorPageSize } = this.state;
let name = this.props.match.params ? this.props.match.params.id : "";
const plugin = this.getPlugin(plugins, name);
- const { id: pluginId } = plugin;
+ const { pluginId } = plugin;
dispatch({
type: "common/enableSelector",
payload: {
@@ -887,17 +887,20 @@ export default class Common extends Component {
pageSize: rulePageSize,
namespaceId: currentNamespaceId,
},
+ callback: () => {
+ this.setState({ ruleSelectedRowKeys: [] });
+ },
});
};
asyncClick = () => {
const { dispatch, plugins, currentNamespaceId } = this.props;
let name = this.props.match.params ? this.props.match.params.id : "";
- const id = this.getPluginId(plugins, name);
+ const pluginId = this.getPluginId(plugins, name);
dispatch({
type: "global/asyncPlugin",
payload: {
- id,
+ pluginId,
namespaceId: currentNamespaceId,
},
});
diff --git a/src/routes/System/Alert/index.js b/src/routes/System/Alert/index.js
index a6304e31..47138529 100644
--- a/src/routes/System/Alert/index.js
+++ b/src/routes/System/Alert/index.js
@@ -26,9 +26,10 @@ import { Type } from "./globalData";
const DEFAULT_ALERT_TYPE = 1;
-@connect(({ alert, loading }) => ({
+@connect(({ alert, loading, global }) => ({
alert,
loading: loading.effects["alert/fetch"],
+ currentNamespaceId: global.currentNamespaceId,
}))
export default class Alert extends Component {
constructor(props) {
@@ -49,13 +50,14 @@ export default class Alert extends Component {
};
getAllAlerts = () => {
- const { dispatch } = this.props;
+ const { dispatch, currentNamespaceId } = this.props;
const { currentPage, pageSize } = this.state;
dispatch({
type: "alert/fetch",
payload: {
currentPage,
pageSize,
+ namespaceId: currentNamespaceId,
},
});
};
diff --git a/src/routes/System/NamespacePlugin/index.js
b/src/routes/System/NamespacePlugin/index.js
index 060f991d..ab77458a 100644
--- a/src/routes/System/NamespacePlugin/index.js
+++ b/src/routes/System/NamespacePlugin/index.js
@@ -216,11 +216,11 @@ export default class NamespacePlugin extends Component {
if (selectedRowKeys && selectedRowKeys.length > 0) {
dispatch({
type: "namespacePlugin/fetchItem",
- payload: { id: selectedRowKeys[0] },
- callback: (user) => {
+ payload: { id: selectedRowKeys[0], namespaceId: currentNamespaceId },
+ callback: (plugin) => {
this.statusSwitch({
list: selectedRowKeys,
- enabled: !user.enabled,
+ enabled: !plugin.enabled,
namespaceId: currentNamespaceId,
callback: () => {
this.setState({ selectedRowKeys: [] });
diff --git a/src/routes/System/User/DataPermModal.js
b/src/routes/System/User/DataPermModal.js
index 827da468..ed1ac63a 100644
--- a/src/routes/System/User/DataPermModal.js
+++ b/src/routes/System/User/DataPermModal.js
@@ -69,11 +69,15 @@ export default class DataPermModal extends Component {
getPluginTreeData = () => {
const { dispatch } = this.props;
+ const { currentNamespaceId } = this.state;
dispatch({
type: "resource/fetchMenuTree",
});
dispatch({
- type: "global/fetchPlugins",
+ type: "global/fetchPluginsByNamespace",
+ payload: {
+ namespaceId: currentNamespaceId,
+ },
});
};
@@ -241,28 +245,30 @@ export default class DataPermModal extends Component {
return;
}
const currentPluginInfo = plugins.find((v) => v.name === plugin.name);
- let currentCategory = treeData.find(
- (tree) => tree.title === currentPluginInfo.role,
- );
- if (!currentCategory) {
- treeData.push({
- title: currentPluginInfo.role,
- key: currentPluginInfo.role,
- selectable: false,
- icon: "unordered-list",
+ if (currentPluginInfo) {
+ let currentCategory = treeData.find(
+ (tree) => tree.title === currentPluginInfo.role,
+ );
+ if (!currentCategory) {
+ treeData.push({
+ title: currentPluginInfo.role,
+ key: currentPluginInfo.role,
+ selectable: false,
+ icon: "unordered-list",
+ sort: plugin.sort,
+ children: [],
+ });
+ currentCategory = treeData[treeData.length - 1];
+ }
+ currentCategory.children.push({
+ key: currentPluginInfo.pluginId,
+ title: titleCase(currentPluginInfo.name),
+ selectable: true,
sort: plugin.sort,
- children: [],
+ icon: plugin.meta.icon,
+ pluginId: currentPluginInfo.pluginId,
});
- currentCategory = treeData[treeData.length - 1];
}
- currentCategory.children.push({
- key: currentPluginInfo.id,
- title: titleCase(currentPluginInfo.name),
- selectable: true,
- sort: plugin.sort,
- icon: plugin.meta.icon,
- pluginId: currentPluginInfo.id,
- });
});
pluginMenuList = treeData;
@@ -424,11 +430,18 @@ export default class DataPermModal extends Component {
handleNamespacesValueChange = (value) => {
const { currentPlugin } = this.state;
+ const { dispatch } = this.props;
this.setState({ currentNamespaceId: value.key }, () => {
if (currentPlugin) {
this.setState({ selectorExpandedRowKeys: [] });
this.getPermissionSelectorList(1);
}
+ dispatch({
+ type: "global/fetchPluginsByNamespace",
+ payload: {
+ namespaceId: value.key,
+ },
+ });
});
};
diff --git a/src/services/api.js b/src/services/api.js
index b014028f..fe1e346e 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -198,7 +198,7 @@ export async function addPlugin(params) {
/* generatePlugin */
export async function generatePlugin({ pluginId, namespaceId }) {
return request(`${baseUrl}/namespace-plugin/${namespaceId}/${pluginId}`, {
- method: `PUT`,
+ method: `POST`,
});
}
@@ -594,7 +594,7 @@ export async function asyncOnePlugin(params) {
// sync by plugin and namespace
export async function asyncByPluginAndNamespace(params) {
return request(
-
`${baseUrl}/namespace-plugin/syncPluginData?id=${params.id}&namespaceId=${params.namespaceId}`,
+
`${baseUrl}/namespace-plugin/syncPluginData?pluginId=${params.pluginId}&namespaceId=${params.namespaceId}`,
{
method: `PUT`,
},
@@ -611,7 +611,7 @@ export async function getPluginDropDownList() {
// get plugin dropdown list by namespace
export async function getPluginDropDownListByNamespace(params) {
return request(
- `${baseUrl}/plugin-template/listByNamespace?namespace=${params.namespace}`,
+
`${baseUrl}/namespace-plugin/listByNamespace?namespace=${params.namespace}`,
{
method: `GET`,
},
@@ -1294,9 +1294,12 @@ export async function deleteNamespace(params) {
/* findNamespacePlugin */
export async function findNamespacePlugin(params) {
- return request(`${baseUrl}/namespace-plugin/detail?${stringify(params)}`, {
- method: `GET`,
- });
+ return request(
+ `${baseUrl}/namespace-plugin/${params.namespaceId}/${params.id}`,
+ {
+ method: `GET`,
+ },
+ );
}
/* getAllNamespacePlugins */
@@ -1331,10 +1334,13 @@ export async function
updateNamespacePluginEnabledByNamespace(params) {
/* updateNamespacePlugin */
export async function updateNamespacePlugin(params) {
- return request(`${baseUrl}/namespace-plugin`, {
- method: `POST`,
- body: params,
- });
+ return request(
+ `${baseUrl}/namespace-plugin/${params.namespaceId}/${params.pluginId}`,
+ {
+ method: `PUT`,
+ body: params,
+ },
+ );
}
/* deletePlugin */