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

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


The following commit(s) were added to refs/heads/master by this push:
     new daded21  feat: refactor publish/offline fe (#991)
daded21 is described below

commit daded2170383c788892a875b8c0a95f7b824bad0
Author: liuxiran <[email protected]>
AuthorDate: Sun Dec 20 22:42:08 2020 -0600

    feat: refactor publish/offline fe (#991)
    
    * feat: refactor online debug fe
    
    * fix: use PATCH instead of PUT
    
    * fix: bug
    
    * fix: code review
    
    * fix(FE): delete route error
    
    Co-authored-by: 琚致远 <[email protected]>
    Co-authored-by: litesun <[email protected]>
---
 web/src/pages/Route/Create.tsx                     |  1 +
 web/src/pages/Route/List.tsx                       | 71 ++++++++++++++++++++--
 .../Route/components/CreateStep4/CreateStep4.tsx   |  3 +-
 web/src/pages/Route/components/Step1/MetaView.tsx  | 11 +++-
 web/src/pages/Route/constants.ts                   |  2 +-
 web/src/pages/Route/locales/en-US.ts               |  3 +
 web/src/pages/Route/locales/zh-CN.ts               |  3 +
 web/src/pages/Route/service.ts                     |  7 +++
 web/src/pages/Route/transform.ts                   |  3 +
 web/src/pages/Route/typing.d.ts                    |  9 ++-
 10 files changed, 100 insertions(+), 13 deletions(-)

diff --git a/web/src/pages/Route/Create.tsx b/web/src/pages/Route/Create.tsx
index 73e3e9e..5755505 100644
--- a/web/src/pages/Route/Create.tsx
+++ b/web/src/pages/Route/Create.tsx
@@ -156,6 +156,7 @@ const Page: React.FC<Props> = (props) => {
           form2={form2}
           upstreamRef={upstreamRef}
           step3Data={step3Data}
+          isEdit={props.route.path.indexOf('edit') > 0}
         />
       );
     }
diff --git a/web/src/pages/Route/List.tsx b/web/src/pages/Route/List.tsx
index 0602eac..30979fc 100644
--- a/web/src/pages/Route/List.tsx
+++ b/web/src/pages/Route/List.tsx
@@ -22,12 +22,37 @@ import { history, useIntl } from 'umi';
 import { PlusOutlined, BugOutlined } from '@ant-design/icons';
 import { timestampToLocaleString } from '@/helpers';
 
-import { fetchList, remove } from './service';
+import { fetchList, remove, updateRouteStatus } from './service';
 import { DebugDrawView } from './components/DebugViews';
 
 const Page: React.FC = () => {
   const ref = useRef<ActionType>();
   const { formatMessage } = useIntl();
+
+  enum RouteStatus {
+    Offline = 0,
+    Publish,
+  }
+
+  const handleTableActionSuccessResponse = (msgTip: string) => {
+    notification.success({
+      message: msgTip,
+    });
+
+    ref.current?.reload();
+  };
+
+  const handlePublishOffline = (rid: string, status: RouteModule.RouteStatus) 
=> {
+    updateRouteStatus(rid, status).then(() => {
+      const actionName = status ? formatMessage({ id: 'page.route.publish' }) 
: formatMessage({ id: 'page.route.offline' })
+      handleTableActionSuccessResponse(
+        `${actionName} ${formatMessage({
+          id: 'menu.routes',
+        })} ${formatMessage({ id: 'component.status.success' })}`,
+      );
+    });
+  }
+
   const [debugDrawVisible, setDebugDrawVisible] = useState(false);
 
   const columns: ProColumns<RouteModule.ResponseBody>[] = [
@@ -66,6 +91,19 @@ const Page: React.FC = () => {
       hideInSearch: true,
     },
     {
+      title: formatMessage({ id: 'page.route.status' }),
+      dataIndex: 'status',
+      render: (_, record) => (
+        <>
+          {record.status ? (
+            <Tag color="green">{formatMessage({ id: 'page.route.published' 
})}</Tag>
+          ) : (
+            <Tag color="red">{formatMessage({ id: 'page.route.unpublished' 
})}</Tag>
+          )}
+        </>
+      ),
+    },
+    {
       title: formatMessage({ id: 'component.global.updateTime' }),
       dataIndex: 'update_time',
       hideInSearch: true,
@@ -85,17 +123,38 @@ const Page: React.FC = () => {
             >
               {formatMessage({ id: 'component.global.edit' })}
             </Button>
+            <Button
+              type="primary"
+              onClick={() => {
+                handlePublishOffline(record.id, RouteStatus.Publish)
+              }}
+              style={{ marginRight: 10 }}
+              disabled={Boolean(record.status)}
+            >
+              {formatMessage({ id: 'page.route.publish' })}
+            </Button>
+            <Popconfirm
+              title={formatMessage({ id: 'page.route.popconfirm.title.offline' 
})}
+              onConfirm={() => {
+                handlePublishOffline(record.id, RouteStatus.Offline)
+              }}
+              okText={formatMessage({ id: 'component.global.confirm' })}
+              cancelText={formatMessage({ id: 'component.global.cancel' })}
+              disabled={Boolean(!record.status)}
+            >
+              <Button type="primary" danger disabled={Boolean(!record.status)}>
+                {formatMessage({ id: 'page.route.offline' })}
+              </Button>
+            </Popconfirm>
             <Popconfirm
               title={formatMessage({ id: 
'component.global.popconfirm.title.delete' })}
               onConfirm={() => {
                 remove(record.id!).then(() => {
-                  notification.success({
-                    message: `${formatMessage({ id: 'component.global.delete' 
})} ${formatMessage({
+                  handleTableActionSuccessResponse(
+                    `${formatMessage({ id: 'component.global.delete' })} 
${formatMessage({
                       id: 'menu.routes',
                     })} ${formatMessage({ id: 'component.status.success' })}`,
-                  });
-                  /* eslint-disable no-unused-expressions */
-                  ref.current?.reload();
+                  );
                 });
               }}
               okText={formatMessage({ id: 'component.global.confirm' })}
diff --git a/web/src/pages/Route/components/CreateStep4/CreateStep4.tsx 
b/web/src/pages/Route/components/CreateStep4/CreateStep4.tsx
index f0c668a..16ba096 100644
--- a/web/src/pages/Route/components/CreateStep4/CreateStep4.tsx
+++ b/web/src/pages/Route/components/CreateStep4/CreateStep4.tsx
@@ -30,6 +30,7 @@ type Props = {
   step3Data: RouteModule.Step3Data;
   advancedMatchingRules: RouteModule.MatchingRule[];
   upstreamRef: any;
+  isEdit?: boolean;
 };
 
 const style = {
@@ -43,7 +44,7 @@ const CreateStep4: React.FC<Props> = ({ form1, form2, 
redirect, upstreamRef, ...
   return (
     <>
       <h2>{formatMessage({ id: 'page.route.steps.stepTitle.defineApiRequest' 
})}</h2>
-      <Step1 {...rest} form={form1} disabled />
+      <Step1 {...rest} form={form1} disabled isEdit />
       {!redirect && (
         <>
           <h2 style={style}>
diff --git a/web/src/pages/Route/components/Step1/MetaView.tsx 
b/web/src/pages/Route/components/Step1/MetaView.tsx
index 7c3053e..a7d86eb 100644
--- a/web/src/pages/Route/components/Step1/MetaView.tsx
+++ b/web/src/pages/Route/components/Step1/MetaView.tsx
@@ -16,11 +16,11 @@
  */
 import React from 'react';
 import Form from 'antd/es/form';
-import { Input } from 'antd';
+import { Input, Switch } from 'antd';
 import { useIntl } from 'umi';
 import { PanelSection } from '@api7-dashboard/ui';
 
-const MetaView: React.FC<RouteModule.Step1PassProps> = ({ disabled }) => {
+const MetaView: React.FC<RouteModule.Step1PassProps> = ({ disabled, isEdit }) 
=> {
   const { formatMessage } = useIntl();
 
   return (
@@ -55,6 +55,13 @@ const MetaView: React.FC<RouteModule.Step1PassProps> = ({ 
disabled }) => {
           disabled={disabled}
         />
       </Form.Item>
+      <Form.Item
+        label={formatMessage({ id: 'page.route.publish' })}
+        name="status"
+        valuePropName="checked"
+      >
+        <Switch disabled={isEdit} />
+      </Form.Item>
     </PanelSection>
   );
 };
diff --git a/web/src/pages/Route/constants.ts b/web/src/pages/Route/constants.ts
index 5490f8f..ee91b1f 100644
--- a/web/src/pages/Route/constants.ts
+++ b/web/src/pages/Route/constants.ts
@@ -43,7 +43,7 @@ export const FORM_ITEM_WITHOUT_LABEL = {
 export const DEFAULT_STEP_1_DATA: RouteModule.Form1Data = {
   name: '',
   desc: '',
-  status: false,
+  status: 1,
   priority: 0,
   websocket: false,
   hosts: [''],
diff --git a/web/src/pages/Route/locales/en-US.ts 
b/web/src/pages/Route/locales/en-US.ts
index 56b9ffc..ebef2c2 100644
--- a/web/src/pages/Route/locales/en-US.ts
+++ b/web/src/pages/Route/locales/en-US.ts
@@ -84,6 +84,9 @@ export default {
   'page.route.status': 'Status',
   'page.route.groupName': 'GroupName',
   'page.route.offline': 'Offline',
+  'page.route.publish': 'Publish',
+  'page.route.published': 'Published',
+  'page.route.unpublished': 'UnPublished',
 
   'page.route.select.option.inputManually': 'Input Manually',
   'page.route.form.itemLabel.domainNameOrIp': 'Domain Name/IP',
diff --git a/web/src/pages/Route/locales/zh-CN.ts 
b/web/src/pages/Route/locales/zh-CN.ts
index f805e67..b2d7bc3 100644
--- a/web/src/pages/Route/locales/zh-CN.ts
+++ b/web/src/pages/Route/locales/zh-CN.ts
@@ -36,6 +36,9 @@ export default {
   'page.route.status': '状态',
   'page.route.groupName': '分组名称',
   'page.route.offline': '下线',
+  'page.route.publish': '发布',
+  'page.route.published': '已发布',
+  'page.route.unpublished': '未发布',
   'page.route.onlineDebug': '在线调试',
 
   // button
diff --git a/web/src/pages/Route/service.ts b/web/src/pages/Route/service.ts
index 8a1fad6..68eb6d3 100644
--- a/web/src/pages/Route/service.ts
+++ b/web/src/pages/Route/service.ts
@@ -86,6 +86,13 @@ export const checkHostWithSSL = (hosts: string[]) =>
     data: hosts,
   });
 
+
+export const updateRouteStatus = (rid: string, status: 
RouteModule.RouteStatus) =>
+  request(`/routes/${rid}`, {
+    method: 'PATCH',
+    data: {status}
+  });
+
 export const debugRoute = (data: RouteModule.debugRequest) => {
   return request('/debug-request-forwarding', {
     method: 'post',
diff --git a/web/src/pages/Route/transform.ts b/web/src/pages/Route/transform.ts
index 28985dd..1a325ff 100644
--- a/web/src/pages/Route/transform.ts
+++ b/web/src/pages/Route/transform.ts
@@ -70,6 +70,9 @@ export const transformStepData = ({
       }
       data.plugins!.redirect = redirect;
     }
+    if (data.status !== undefined) {
+      data.status = Number(data.status);
+    }
 
     // Remove some of the frontend custom variables
     return omit(data, [
diff --git a/web/src/pages/Route/typing.d.ts b/web/src/pages/Route/typing.d.ts
index 824fa82..7710337 100644
--- a/web/src/pages/Route/typing.d.ts
+++ b/web/src/pages/Route/typing.d.ts
@@ -35,7 +35,7 @@ declare namespace RouteModule {
     desc: string;
     uris: string[];
     hosts: string[];
-    status: boolean;
+    status: number;
   };
 
   type Step3Data = {
@@ -70,7 +70,7 @@ declare namespace RouteModule {
   // Request Body or Response Data for API
   type Body = {
     id?: number;
-    status: boolean;
+    status: number;
     name: string;
     desc: string;
     priority?: number;
@@ -140,7 +140,7 @@ declare namespace RouteModule {
     redirectOption: 'forceHttps' | 'customRedirect' | 'disabled';
     redirectURI?: string;
     ret_code?: number;
-    status: boolean;
+    status: number;
     enable_websocket?: boolean;
   };
 
@@ -230,8 +230,11 @@ declare namespace RouteModule {
     hosts?: string[];
     create_time: number;
     update_time: number;
+    status: number;
   };
 
+  type RouteStatus = 0 | 1;
+
   // TODO: grpc and websocket
   type debugRequest = {
     url: string;

Reply via email to