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

dengliming 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 30ed9a23 [type:feature] adapt namesapce config export/import (#497)
30ed9a23 is described below

commit 30ed9a23daf09277217642a9b429259932d80191
Author: aias00 <rok...@163.com>
AuthorDate: Sun Nov 10 20:16:04 2024 +0800

    [type:feature] adapt namesapce config export/import (#497)
    
    * remove 'resource' button in namespacePlugin
    
    * fix es lint
    
    * fix namespace sync bug
    
    * namespace config import adapt
    
    * [type:feature]adapt_namespace_export
    
    * [type:feature]adapt_namespace_export
---
 src/components/GlobalHeader/ExportModal.js | 151 +++++++++++++++++++++++++++++
 src/components/GlobalHeader/index.js       |  30 +++++-
 src/models/common.js                       |   4 +
 src/services/api.js                        |  10 ++
 4 files changed, 191 insertions(+), 4 deletions(-)

diff --git a/src/components/GlobalHeader/ExportModal.js 
b/src/components/GlobalHeader/ExportModal.js
new file mode 100644
index 00000000..e6dfceca
--- /dev/null
+++ b/src/components/GlobalHeader/ExportModal.js
@@ -0,0 +1,151 @@
+/*
+ * 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, { Component, forwardRef } from "react";
+import { Modal, Form, Button, Dropdown, Menu, Icon } from "antd";
+import { connect } from "dva";
+import { getIntlContent } from "../../utils/IntlUtils";
+import { defaultNamespaceId } from "../_utils/utils";
+
+const FormItem = Form.Item;
+
+const NamespaceSelector = forwardRef(
+  ({ onChange, currentNamespaceId, namespaces }) => {
+    const handleNamespaceChange = (value) => {
+      onChange(value.key);
+    };
+    return (
+      <Dropdown
+        overlay={
+          <Menu onClick={handleNamespaceChange}>
+            {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>
+    );
+  },
+);
+
+@connect(({ global }) => ({
+  platform: global.platform,
+  namespaces: global.namespaces,
+}))
+class ExportModal extends Component {
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      currentNamespaceId: defaultNamespaceId,
+    };
+  }
+
+  handleSubmit = (e) => {
+    const { form, handleOk } = this.props;
+    e.preventDefault();
+    form.validateFieldsAndScroll((err, values) => {
+      if (!err) {
+        let { namespace, file } = values;
+        handleOk({ namespace, file });
+      }
+    });
+  };
+
+  handleNamespacesValueChange = (value) => {
+    this.setState({ currentNamespaceId: value });
+  };
+
+  render() {
+    let { handleCancel, form, config, namespaces } = this.props;
+    let { currentNamespaceId } = this.state;
+    const { getFieldDecorator } = form;
+    const formItemLayout = {
+      labelCol: {
+        sm: { span: 7 },
+      },
+      wrapperCol: {
+        sm: { span: 17 },
+      },
+    };
+    if (config) {
+      config = JSON.parse(config);
+    }
+
+    return (
+      <Modal
+        width={520}
+        centered
+        title={getIntlContent("SHENYU.COMMON.EXPORT")}
+        visible
+        okText={getIntlContent("SHENYU.COMMON.SURE")}
+        cancelText={getIntlContent("SHENYU.COMMON.CALCEL")}
+        onOk={this.handleSubmit}
+        onCancel={handleCancel}
+      >
+        <Form onSubmit={this.handleSubmit} className="login-form">
+          <FormItem
+            {...formItemLayout}
+            label={getIntlContent("SHENYU.SYSTEM.NAMESPACE")}
+          >
+            {getFieldDecorator("namespace", {
+              rules: [
+                {
+                  required: true,
+                },
+              ],
+              initialValue: currentNamespaceId,
+              valuePropName: "namespace",
+            })(
+              <NamespaceSelector
+                onChange={this.handleNamespacesValueChange}
+                currentNamespaceId={currentNamespaceId}
+                namespaces={namespaces}
+              />,
+            )}
+          </FormItem>
+        </Form>
+      </Modal>
+    );
+  }
+}
+
+export default Form.create()(ExportModal);
diff --git a/src/components/GlobalHeader/index.js 
b/src/components/GlobalHeader/index.js
index 5eca62f9..4e22a48c 100644
--- a/src/components/GlobalHeader/index.js
+++ b/src/components/GlobalHeader/index.js
@@ -29,6 +29,7 @@ import {
 import { connect } from "dva";
 import { withRouter } from "dva/router";
 import AddModal from "./AddModal";
+import ExportModal from "./ExportModal";
 import ImportResultModal from "./ImportResultModal";
 import styles from "./index.less";
 import { getCurrentLocale, getIntlContent } from "../../utils/IntlUtils";
@@ -226,10 +227,31 @@ class GlobalHeader extends PureComponent {
 
   // export configs
   exportConfigClick = () => {
-    const { dispatch } = this.props;
-    dispatch({
-      type: "common/exportAll",
+    this.setState({
+      popup: (
+        <ExportModal
+          disabled={false}
+          handleOk={(values) => {
+            const { dispatch } = this.props;
+            dispatch({
+              type: "common/exportAll",
+              payload: values,
+              callback: (res) => {
+                this.closeModal(true);
+                this.showImportRestlt(JSON.parse(res));
+              },
+            });
+          }}
+          handleCancel={() => {
+            this.closeModal();
+          }}
+        />
+      ),
     });
+    // const { dispatch } = this.props;
+    // dispatch({
+    //   type: "common/exportAll",
+    // });
   };
 
   checkAuth = (perms) => {
@@ -337,7 +359,7 @@ class GlobalHeader extends PureComponent {
           {this.checkAuth("system:manager:exportConfig") && (
             <div className={styles.item}>
               <Button onClick={this.exportConfigClick}>
-                <Icon type="import" /> {getIntlContent("SHENYU.COMMON.EXPORT")}
+                <Icon type="export" /> {getIntlContent("SHENYU.COMMON.EXPORT")}
               </Button>
             </div>
           )}
diff --git a/src/models/common.js b/src/models/common.js
index e4eafb8c..f63df052 100644
--- a/src/models/common.js
+++ b/src/models/common.js
@@ -256,6 +256,10 @@ export default {
       yield call(asyncConfigExport);
     },
 
+    *exportByNamespace(_, { call }) {
+      yield call(asyncConfigExport);
+    },
+
     *import(params, { call }) {
       const { payload, callback } = params;
       const json = yield call(asyncConfigImport, payload);
diff --git a/src/services/api.js b/src/services/api.js
index 24f887df..f17e745f 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -546,6 +546,16 @@ export async function asyncConfigExport() {
   });
 }
 
+// export configs by namespace
+export async function asyncConfigExportByNamespace(params) {
+  return download(
+    `${baseUrl}/configs/exportByNamespace?namespaceId=${params.namespaceId}`,
+    {
+      method: `GET`,
+    },
+  );
+}
+
 // import configs
 export async function asyncConfigImport(params) {
   const formData = new FormData();

Reply via email to