This is an automated email from the ASF dual-hosted git repository. kerwin612 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 8a24fc51 [Feature] Add namespace to select common components (#462) 8a24fc51 is described below commit 8a24fc51f02b3731ab64f21fe29db66affa89e27 Author: VampireAchao <ac...@apache.org> AuthorDate: Thu Jul 25 08:53:19 2024 +0800 [Feature] Add namespace to select common components (#462) * fix pluginList sync bug * fix cr * [Improve] Add namespace to select common components * [Improve] Add namespace to sync plugin * [Fix] fix namespace single delete problem * [Improve] update namespace style to dropdown * [Improve] update namespace style for tag * [Fix] fix ci * Revert a wrong conflict resolution --------- Co-authored-by: ‘xcsnx’ <‘1192709...@qq.com’> Co-authored-by: chenshinan <1192709...@qq.com> Co-authored-by: Kerwin Bryant <kerwin...@qq.com> --- src/components/GlobalHeader/index.js | 53 ++++++++++++++++++++++++++++-- src/models/global.js | 24 ++++++++++++++ src/models/namespacePlugin.js | 4 +-- src/routes/Plugin/Common/index.js | 3 +- src/routes/System/Namespace/index.js | 33 ++++++++++++++++--- src/routes/System/NamespacePlugin/index.js | 43 ++++++++++++------------ src/services/api.js | 11 ++++--- 7 files changed, 135 insertions(+), 36 deletions(-) diff --git a/src/components/GlobalHeader/index.js b/src/components/GlobalHeader/index.js index 36cea0e5..bd985898 100644 --- a/src/components/GlobalHeader/index.js +++ b/src/components/GlobalHeader/index.js @@ -16,12 +16,12 @@ */ import React, { PureComponent } from "react"; -import { Dropdown, Form, Icon, Input, Menu, Modal, Button } from "antd"; +import { Button, Dropdown, Form, Icon, Input, Menu, Modal } from "antd"; import { connect } from "dva"; import AddModal from "./AddModal"; import ImportResultModal from "./ImportResultModal"; import styles from "./index.less"; -import { getIntlContent, getCurrentLocale } from "../../utils/IntlUtils"; +import { getCurrentLocale, getIntlContent } from "../../utils/IntlUtils"; import { checkUserPassword } from "../../services/api"; import { emit } from "../../utils/emit"; @@ -48,6 +48,8 @@ const TranslationOutlined = (props) => ( @connect(({ global, manage, loading }) => ({ manage, permissions: global.permissions, + namespaces: global.namespaces, + currentNamespaceId: global.currentNamespaceId, loading: loading.effects["manage/update"], })) @Form.create({}) @@ -110,12 +112,20 @@ class GlobalHeader extends PureComponent { } }); } + this.fetchNamespaces(); } componentWillUnmount() { this.setState = () => false; } + fetchNamespaces = () => { + const { dispatch } = this.props; + dispatch({ + type: "global/fetchNamespaces", + }); + }; + handleLocalesValueChange = (value) => { const { changeLocalName } = this.props; if (value.key === "0") { @@ -136,6 +146,14 @@ class GlobalHeader extends PureComponent { getCurrentLocale(this.state.localeName); }; + handleNamespacesValueChange = (value) => { + const { dispatch } = this.props; + dispatch({ + type: "global/saveCurrentNamespaceId", + payload: value.key, + }); + }; + importConfigClick = () => { this.setState({ popup: ( @@ -204,6 +222,8 @@ class GlobalHeader extends PureComponent { form: { getFieldDecorator, resetFields, validateFields, getFieldValue }, dispatch, loading, + namespaces, + currentNamespaceId, } = this.props; const { popup, userName, visible } = this.state; const menu = ( @@ -237,6 +257,35 @@ class GlobalHeader extends PureComponent { <span className={styles.text}> Apache ShenYu Gateway Management System </span> + <div className={styles.item}> + <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> + { + namespaces.find( + (namespace) => currentNamespaceId === namespace.namespaceId, + )?.name + } + </Button> + </Dropdown> + </div> <div> <div className={styles.item}> <Dropdown placement="bottomCenter" overlay={this.state.help}> diff --git a/src/models/global.js b/src/models/global.js index 17096de5..2ddba64c 100644 --- a/src/models/global.js +++ b/src/models/global.js @@ -20,6 +20,7 @@ import { routerRedux } from "dva/router"; import { queryPlatform, getAllPlugins, + getNamespaceList, asyncOnePlugin, getUserPermissionByToken, } from "../services/api"; @@ -35,6 +36,8 @@ export default { currentRouter: {}, permissions: {}, language: "", + namespaces: [], + currentNamespaceId: "649330b6-c2d7-4edc-be8e-8a54df9eb385", }, effects: { @@ -47,6 +50,15 @@ export default { }); } }, + *fetchNamespaces(_, { call, put }) { + const json = yield call(getNamespaceList); + if (json.code === 200) { + yield put({ + type: "saveNamespaces", + payload: json.data, + }); + } + }, *fetchPlugins({ payload }, { call, put }) { const { callback } = payload ?? {}; const params = { @@ -153,6 +165,18 @@ export default { platform: payload, }; }, + saveNamespaces(state, { payload }) { + return { + ...state, + namespaces: payload, + }; + }, + saveCurrentNamespaceId(state, { payload }) { + return { + ...state, + currentNamespaceId: payload, + }; + }, savePlugins(state, { payload }) { return { ...state, diff --git a/src/models/namespacePlugin.js b/src/models/namespacePlugin.js index ad8fc328..9d349886 100644 --- a/src/models/namespacePlugin.js +++ b/src/models/namespacePlugin.js @@ -123,8 +123,8 @@ export default { *reload(params, { put }) { const { fetchValue } = params; - const { name, currentPage, enabled, pageSize } = fetchValue; - const payload = { name, enabled, currentPage, pageSize }; + const { name, currentPage, enabled, pageSize, namespaceId } = fetchValue; + const payload = { name, enabled, currentPage, pageSize, namespaceId }; yield put({ type: "fetch", payload }); }, diff --git a/src/routes/Plugin/Common/index.js b/src/routes/Plugin/Common/index.js index ad859c31..79788564 100755 --- a/src/routes/Plugin/Common/index.js +++ b/src/routes/Plugin/Common/index.js @@ -835,13 +835,14 @@ export default class Common extends Component { }; asyncClick = () => { - const { dispatch, plugins } = this.props; + const { dispatch, plugins, currentNamespaceId } = this.props; let name = this.props.match.params ? this.props.match.params.id : ""; const id = this.getPluginId(plugins, name); dispatch({ type: "global/asyncPlugin", payload: { id, + namespaceId: currentNamespaceId, }, }); }; diff --git a/src/routes/System/Namespace/index.js b/src/routes/System/Namespace/index.js index 3cdda422..fc450057 100644 --- a/src/routes/System/Namespace/index.js +++ b/src/routes/System/Namespace/index.js @@ -16,7 +16,7 @@ */ import React, { Component } from "react"; -import { Table, Input, Button, message, Popconfirm } from "antd"; +import { Button, Input, message, Popconfirm, Table } from "antd"; import { connect } from "dva"; import { resizableComponents } from "../../../utils/resizable"; import AddModal from "./AddModal"; @@ -28,6 +28,7 @@ import { refreshAuthMenus } from "../../../utils/AuthRoute"; namespace, authMenu: resource.authMenu, language: global.language, + currentNamespaceId: global.currentNamespaceId, loading: loading.effects["namespace/fetch"], })) export default class Namespace extends Component { @@ -40,7 +41,6 @@ export default class Namespace extends Component { pageSize: 12, selectedRowKeys: [], name: "", - namespaceId: "", // eslint-disable-next-line react/no-unused-state enabled: null, popup: "", @@ -83,7 +83,8 @@ export default class Namespace extends Component { }; currentQueryPayload = (override) => { - const { name, namespaceId, currentPage, pageSize } = this.state; + const { name, currentPage, pageSize } = this.state; + const { namespaceId } = this.props; return { name, namespaceId, @@ -142,6 +143,7 @@ export default class Namespace extends Component { }, fetchValue: this.currentQueryPayload(), callback: () => { + dispatch({ type: "global/fetchNamespaces" }); this.closeModal(); }, }); @@ -168,9 +170,16 @@ export default class Namespace extends Component { this.setState({ currentPage: 1 }, this.query); }; - deleteClick = () => { - const { dispatch } = this.props; + deleteClick = (record) => { + const { + dispatch, + currentNamespaceId, + namespace: { namespaceList }, + } = this.props; const { selectedRowKeys } = this.state; + if (record) { + selectedRowKeys.push(record.id); + } if (selectedRowKeys && selectedRowKeys.length > 0) { dispatch({ type: "namespace/delete", @@ -183,6 +192,19 @@ export default class Namespace extends Component { callback: () => { this.setState({ selectedRowKeys: [] }); refreshAuthMenus({ dispatch }); + let deletedCurrentNamespace = + namespaceList.find((namespace) => + selectedRowKeys.some( + (namespaceId) => namespaceId === namespace.id, + ), + )?.namespaceId === currentNamespaceId; + if (deletedCurrentNamespace) { + dispatch({ + type: "global/saveCurrentNamespaceId", + payload: "649330b6-c2d7-4edc-be8e-8a54df9eb385", + }); + } + dispatch({ type: "global/fetchNamespaces" }); }, }); } else { @@ -209,6 +231,7 @@ export default class Namespace extends Component { callback: () => { this.closeModal(true); refreshAuthMenus({ dispatch }); + dispatch({ type: "global/fetchNamespaces" }); }, }); }} diff --git a/src/routes/System/NamespacePlugin/index.js b/src/routes/System/NamespacePlugin/index.js index 5543517f..baceaa23 100644 --- a/src/routes/System/NamespacePlugin/index.js +++ b/src/routes/System/NamespacePlugin/index.js @@ -17,16 +17,16 @@ import React, { Component } from "react"; import { - Table, - Input, Button, + Input, message, Popconfirm, - Select, Popover, + Select, + Switch, + Table, Tag, Typography, - Switch, } from "antd"; import { connect } from "dva"; import { Link } from "dva/router"; @@ -47,6 +47,7 @@ const { Option } = Select; namespacePlugin, authMenu: resource.authMenu, language: global.language, + currentNamespaceId: global.currentNamespaceId, loading: loading.effects["namespacePlugin/fetch"], })) export default class NamespacePlugin extends Component { @@ -57,8 +58,6 @@ export default class NamespacePlugin extends Component { this.state = { currentPage: 1, pageSize: 12, - // todo:[To be refactored with namespace] Temporarily hardcode - namespaceId: "649330b6-c2d7-4edc-be8e-8a54df9eb385", selectedRowKeys: [], name: "", enabled: null, @@ -75,13 +74,16 @@ export default class NamespacePlugin extends Component { this.initNamespacePluginColumns(); } - componentDidUpdate() { - const { language } = this.props; + componentDidUpdate(prevProps) { + const { language, currentNamespaceId } = this.props; const { localeName } = this.state; if (language !== localeName) { this.initNamespacePluginColumns(); this.changeLocale(language); } + if (prevProps.currentNamespaceId !== currentNamespaceId) { + this.query(); + } } handleResize = @@ -98,15 +100,16 @@ export default class NamespacePlugin extends Component { }; onSelectChange = (selectedRowKeys) => { - this.setState({ selectedRowKeys }, this.query); + this.setState({ selectedRowKeys }); }; currentQueryPayload = (override) => { - const { name, enabled, currentPage, pageSize, namespaceId } = this.state; + const { name, enabled, currentPage, pageSize } = this.state; + const { currentNamespaceId } = this.props; return { name, enabled, - namespaceId, + namespaceId: currentNamespaceId, currentPage, pageSize, ...override, @@ -138,11 +141,10 @@ export default class NamespacePlugin extends Component { }; editClick = (record) => { - const { dispatch } = this.props; + const { dispatch, currentNamespaceId } = this.props; getUpdateModal({ id: record.id, - // todo:[To be refactored with namespace] Temporarily hardcode - namespaceId: "649330b6-c2d7-4edc-be8e-8a54df9eb385", + namespaceId: currentNamespaceId, dispatch, fetchValue: this.currentQueryPayload(), callback: (popup) => { @@ -191,15 +193,14 @@ export default class NamespacePlugin extends Component { }; deleteClick = () => { - const { dispatch } = this.props; + const { dispatch, currentNamespaceId } = this.props; const { selectedRowKeys } = this.state; if (selectedRowKeys && selectedRowKeys.length > 0) { dispatch({ type: "namespacePlugin/delete", payload: { list: selectedRowKeys, - // todo:[To be refactored with namespace] Temporarily hardcode - namespaceId: "649330b6-c2d7-4edc-be8e-8a54df9eb385", + namespaceId: currentNamespaceId, }, fetchValue: this.currentQueryPayload({ pageSize: 12, @@ -230,22 +231,20 @@ export default class NamespacePlugin extends Component { // 批量启用或禁用 enableClick = () => { - const { dispatch } = this.props; + const { dispatch, currentNamespaceId } = this.props; const { selectedRowKeys } = this.state; if (selectedRowKeys && selectedRowKeys.length > 0) { dispatch({ type: "namespacePlugin/fetchItem", payload: { id: selectedRowKeys[0], - // todo:[To be refactored with namespace] Temporarily hardcode - namespaceId: "649330b6-c2d7-4edc-be8e-8a54df9eb385", + namespaceId: currentNamespaceId, }, callback: (user) => { this.statusSwitch({ list: selectedRowKeys, enabled: !user.enabled, - // todo:[To be refactored with namespace] Temporarily hardcode - namespaceId: "649330b6-c2d7-4edc-be8e-8a54df9eb385", + namespaceId: currentNamespaceId, callback: () => { this.setState({ selectedRowKeys: [] }); }, diff --git a/src/services/api.js b/src/services/api.js index 13ebd5f6..e245eea2 100644 --- a/src/services/api.js +++ b/src/services/api.js @@ -552,9 +552,8 @@ export async function asyncConfigImport(params) { // 同步单个插件 export async function asyncOnePlugin(params) { - // todo:[To be refactored with namespace] Temporarily hardcode return request( - `${baseUrl}/namespacePlugin/syncPluginData/id=${params.id}&namespaceId=649330b6-c2d7-4edc-be8e-8a54df9eb385`, + `${baseUrl}/namespacePlugin/syncPluginData/id=${params.id}&namespaceId=${params.namespaceId}`, { method: `PUT`, }, @@ -1135,6 +1134,12 @@ export function updateDiscoveryUpstream(discoveryHandlerId, upstreams) { }); } +/* getNamespaceList */ +export async function getNamespaceList() { + return request(`${baseUrl}/namespace/list`, { + method: `GET`, + }); +} /* getAllNamespaces */ export async function getAllNamespaces(params) { return request(`${baseUrl}/namespace/findPageByQuery?${stringify(params)}`, { @@ -1178,8 +1183,6 @@ export async function findNamespacePlugin(params) { /* getAllNamespacePlugins */ export async function getAllNamespacePlugins(params) { - // todo:[To be refactored with namespace] Temporarily hardcode - params.namespaceId = "649330b6-c2d7-4edc-be8e-8a54df9eb385"; return request(`${baseUrl}/namespacePlugin?${stringify(params)}`, { method: `GET`, });