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;