You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by ju...@apache.org on 2020/03/13 03:41:57 UTC

[incubator-apisix-dashboard] branch next updated: feat: added edit route (#154)

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

juzhiyuan pushed a commit to branch next
in repository https://gitbox.apache.org/repos/asf/incubator-apisix-dashboard.git


The following commit(s) were added to refs/heads/next by this push:
     new a1bd1e6  feat: added  edit route (#154)
a1bd1e6 is described below

commit a1bd1e60b23f5598a314fbc698c64bd2e0717e8c
Author: 琚致远 <ju...@apache.org>
AuthorDate: Fri Mar 13 11:41:46 2020 +0800

    feat: added  edit route (#154)
    
    * feat: added  edit route
    
    * feat: initial ssl detail page
    
    * feat: added detail page
    
    * remove useless codes
---
 config/config.ts                     |  12 ++++
 src/locales/en-US/component.ts       |  15 ++++-
 src/locales/en-US/menu.ts            |   1 +
 src/locales/zh-CN/component.ts       |  11 ++++
 src/locales/zh-CN/menu.ts            |   1 +
 src/pages/SSLModule/detail/index.tsx | 109 +++++++++++++++++++++++++++++++++++
 src/pages/SSLModule/list/index.tsx   |   8 +++
 src/services/ssl.ts                  |   8 +--
 src/typings.d.ts                     |   2 +
 src/utils/request.ts                 |   4 +-
 src/utils/utils.ts                   |  13 +++++
 11 files changed, 176 insertions(+), 8 deletions(-)

diff --git a/config/config.ts b/config/config.ts
index 687b505..13a9a3b 100644
--- a/config/config.ts
+++ b/config/config.ts
@@ -128,6 +128,18 @@ export default {
                   name: 'list',
                   component: './SSLModule/list',
                 },
+                {
+                  path: '/ssl/:key/edit',
+                  name: 'edit',
+                  component: './SSLModule/detail',
+                  hideInMenu: true,
+                },
+                {
+                  path: '/ssl/create',
+                  name: 'create',
+                  component: './SSLModule/detail',
+                  hideInMenu: true,
+                },
               ],
             },
             {
diff --git a/src/locales/en-US/component.ts b/src/locales/en-US/component.ts
index b3bc39e..112f2ef 100644
--- a/src/locales/en-US/component.ts
+++ b/src/locales/en-US/component.ts
@@ -4,11 +4,22 @@ export default {
   'component.tagSelect.all': 'All',
   'component.global.remove': 'Remove',
   'component.global.cancel': 'Cancel',
+  'component.global.submit': 'Submit',
+  'component.global.create': 'Create',
+  'component.global.save': 'Save',
   'component.global.edit': 'Edit',
   'component.global.action': 'Action',
+  'component.global.update': 'Update',
+  'component.global.get': 'Get',
+  'component.status.success': 'Successfully',
+  'component.status.fail': 'Failed',
   // SSL Module
   'component.ssl.removeSSLItemModalContent': 'You are going to remove this item!',
   'component.ssl.removeSSLItemModalTitle': 'SSL Remove Alert',
-  'component.ssl.fetchSSLListSuccess': 'fetch SSL list successfully',
-  'component.ssl.removeSSLSuccess': 'remove target SSL successfully',
+  'component.ssl.fetchSSLListSuccess': 'Fetch SSL list successfully',
+  'component.ssl.removeSSLSuccess': 'Remove target SSL successfully',
+  'component.ssl.fieldSNIInvalid': 'Please check SNI',
+  'component.ssl.fieldKeyInvalid': 'Please check Key',
+  'component.ssl.fieldCertInvalid': 'Please check Cert',
+  'component.ssl.invalidKey': 'Invalid Key',
 };
diff --git a/src/locales/en-US/menu.ts b/src/locales/en-US/menu.ts
index cc8862a..de2af02 100644
--- a/src/locales/en-US/menu.ts
+++ b/src/locales/en-US/menu.ts
@@ -52,4 +52,5 @@ export default {
   'menu.ssl': 'SSL',
   'menu.ssl.list': 'SSL List',
   'menu.ssl.edit': 'Edit',
+  'menu.ssl.create': 'Create',
 };
diff --git a/src/locales/zh-CN/component.ts b/src/locales/zh-CN/component.ts
index b8c505e..3e77ed0 100644
--- a/src/locales/zh-CN/component.ts
+++ b/src/locales/zh-CN/component.ts
@@ -4,11 +4,22 @@ export default {
   'component.tagSelect.all': '全部',
   'component.global.remove': '移除',
   'component.global.cancel': '取消',
+  'component.global.submit': '提交',
+  'component.global.create': '创建',
+  'component.global.save': '保存',
   'component.global.edit': '编辑',
   'component.global.action': '操作',
+  'component.global.update': '更新',
+  'component.global.get': '获取',
+  'component.status.success': '成功',
+  'component.status.fail': '失败',
   // SSL 模块
   'component.ssl.removeSSLItemModalContent': '确定要移除该项吗?',
   'component.ssl.removeSSLItemModalTitle': '移除 SSL',
   'component.ssl.fetchSSLListSuccess': '获取 SSL 列表成功',
   'component.ssl.removeSSLSuccess': '移除 SSL 成功',
+  'component.ssl.fieldSNIInvalid': '请检查 SNI 值',
+  'component.ssl.fieldKeyInvalid': '请检查 Key 值',
+  'component.ssl.fieldCertInvalid': '请检查 Cert 值',
+  'component.ssl.invalidKey': '非法的 Key',
 };
diff --git a/src/locales/zh-CN/menu.ts b/src/locales/zh-CN/menu.ts
index 1b0aa04..3ba056d 100644
--- a/src/locales/zh-CN/menu.ts
+++ b/src/locales/zh-CN/menu.ts
@@ -52,4 +52,5 @@ export default {
   'menu.ssl': 'SSL',
   'menu.ssl.list': 'SSL 列表',
   'menu.ssl.edit': '编辑',
+  'menu.ssl.create': '创建',
 };
diff --git a/src/pages/SSLModule/detail/index.tsx b/src/pages/SSLModule/detail/index.tsx
new file mode 100644
index 0000000..6cf25d9
--- /dev/null
+++ b/src/pages/SSLModule/detail/index.tsx
@@ -0,0 +1,109 @@
+import React, { useState, useEffect } from 'react';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import { useParams } from 'dva';
+import { Form, Input, Card, Button, notification } from 'antd';
+import { formatMessage } from 'umi-plugin-react/locale';
+
+import { getPageMode } from '@/utils/utils';
+import {
+  fetchItem as fetchSSLItem,
+  create as createSSL,
+  update as updateSSL,
+} from '@/services/ssl';
+import { useForm } from 'antd/es/form/util';
+
+const layout = {
+  wrapperCol: { span: 8 },
+};
+
+const Detail: React.FC = () => {
+  const [mode] = useState<PageMode>(getPageMode());
+  const { key } = useParams();
+  const [form] = useForm();
+
+  useEffect(() => {
+    if (mode === 'EDIT' && key) {
+      fetchSSLItem(key).then(data => {
+        form.setFieldsValue(data.value);
+      });
+    }
+  }, [mode]);
+
+  const onFinish = (values: any) => {
+    if (mode === 'EDIT' && key) {
+      updateSSL(key, values).then(() => {
+        notification.success({
+          message: `${formatMessage({ id: 'component.global.update' })} SSL ${formatMessage({
+            id: 'component.status.success',
+          }).toLowerCase()}`,
+        });
+
+        window.history.go(-1);
+      });
+    }
+
+    if (mode === 'CREATE') {
+      createSSL(values).then(() => {
+        notification.success({
+          message: `${formatMessage({ id: 'component.global.create' })} SSL ${formatMessage({
+            id: 'component.status.success',
+          }).toLowerCase()}`,
+        });
+
+        window.history.go(-1);
+      });
+    }
+  };
+
+  return (
+    <PageHeaderWrapper>
+      <Card>
+        <Form {...layout} form={form} onFinish={onFinish}>
+          <Form.Item
+            label="SNI"
+            name="sni"
+            rules={[
+              { required: true, message: formatMessage({ id: 'component.ssl.fieldSNIInvalid' }) },
+            ]}
+          >
+            <Input />
+          </Form.Item>
+
+          <Form.Item
+            label="Cert"
+            name="cert"
+            rules={[
+              { required: true, message: formatMessage({ id: 'component.ssl.fieldCertInvalid' }) },
+            ]}
+          >
+            <Input.TextArea rows={6} />
+          </Form.Item>
+
+          <Form.Item
+            label="Key"
+            name="key"
+            rules={[
+              { required: true, message: formatMessage({ id: 'component.ssl.fieldKeyInvalid' }) },
+            ]}
+          >
+            <Input.TextArea rows={6} />
+          </Form.Item>
+
+          <Form.Item>
+            <Button style={{ marginRight: 10 }}>
+              {formatMessage({ id: 'component.global.cancel' })}
+            </Button>
+
+            <Button htmlType="submit" type="primary">
+              {mode === 'CREATE'
+                ? formatMessage({ id: 'component.global.create' })
+                : formatMessage({ id: 'component.global.save' })}
+            </Button>
+          </Form.Item>
+        </Form>
+      </Card>
+    </PageHeaderWrapper>
+  );
+};
+
+export default Detail;
diff --git a/src/pages/SSLModule/list/index.tsx b/src/pages/SSLModule/list/index.tsx
index f06f424..cff1c43 100644
--- a/src/pages/SSLModule/list/index.tsx
+++ b/src/pages/SSLModule/list/index.tsx
@@ -4,6 +4,7 @@ import ProTable, { ProColumns, ActionType } from '@ant-design/pro-table';
 import { Button, Modal, notification } from 'antd';
 import { router } from 'umi';
 import { formatMessage } from 'umi-plugin-react/locale';
+import { PlusOutlined } from '@ant-design/icons';
 
 import { fetchList as fetchSSLList, remove as removeSSL } from '@/services/ssl';
 import { SSL } from '@/models/ssl';
@@ -37,6 +38,7 @@ const List: React.FC = () => {
     {
       title: 'ID',
       dataIndex: 'displayKey',
+      sortOrder: 'descend',
     },
     {
       title: 'SNI',
@@ -69,6 +71,12 @@ const List: React.FC = () => {
         search={false}
         columns={columns}
         actionRef={tableRef}
+        toolBarRender={() => [
+          <Button type="primary" onClick={() => router.push(`/ssl/create`)}>
+            <PlusOutlined />
+            {formatMessage({ id: 'component.global.create' })}
+          </Button>,
+        ]}
       />
     </PageHeaderWrapper>
   );
diff --git a/src/services/ssl.ts b/src/services/ssl.ts
index cd51a25..4d96c6f 100644
--- a/src/services/ssl.ts
+++ b/src/services/ssl.ts
@@ -4,8 +4,8 @@ import { SSL } from '@/models/ssl';
 
 export const fetchList = () => request('/api/ssl').then(data => transformFetchListData<SSL>(data));
 
-export const fetchItem = (id: number) =>
-  request(`/api/ssl/${id}`).then(data => transformFetchItemData<SSL>(data));
+export const fetchItem = (key: string) =>
+  request(`/api/ssl/${key}`).then(data => transformFetchItemData<SSL>(data));
 
 export const remove = (key: string) => request.delete(`/api/ssl/${key}`);
 
@@ -14,7 +14,7 @@ export const create = (data: SSL) =>
     data,
   });
 
-export const update = (id: number, data: SSL) =>
-  request.put(`/api/ssl/${id}`, {
+export const update = (key: string, data: SSL) =>
+  request.put(`/api/ssl/${key}`, {
     data,
   });
diff --git a/src/typings.d.ts b/src/typings.d.ts
index eb1d955..c2f9e64 100644
--- a/src/typings.d.ts
+++ b/src/typings.d.ts
@@ -36,3 +36,5 @@ declare let ga: Function;
 declare let ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: 'site' | undefined;
 
 declare const REACT_APP_ENV: 'test' | 'dev' | 'pre' | false;
+
+declare type PageMode = 'CREATE' | 'EDIT' | 'VIEW';
diff --git a/src/utils/request.ts b/src/utils/request.ts
index 849bf1c..a58037a 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -29,10 +29,10 @@ const codeMessage = {
 const errorHandler = (error: { response: Response; data: any }): Promise<Response> => {
   const { response } = error;
   if (response && response.status) {
-    const errorText = error.data.message || codeMessage[response.status];
+    const errorText = error.data.message || error.data.error_msg || codeMessage[response.status];
 
     notification.error({
-      message: `请求错误,错误码: ${error.data.errorCode}`,
+      message: `请求错误,错误码: ${error.data.errorCode || response.status}`,
       description: errorText,
     });
   } else if (!response) {
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 9ba73c2..9a5c445 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -63,3 +63,16 @@ export const getRouteAuthority = (path: string, routeData: Route[]) => {
   });
   return authorities;
 };
+
+export const getPageMode = (): PageMode => {
+  const { pathname } = window.location;
+  if (/edit$/.test(pathname)) {
+    return 'EDIT';
+  }
+
+  if (/create$/.test(pathname)) {
+    return 'CREATE';
+  }
+
+  return 'VIEW';
+};