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`,
   });

Reply via email to