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 2021/04/02 02:08:41 UTC
[apisix-dashboard] branch master updated: feat: Support duplicate
one existing Route (#1558)
This is an automated email from the ASF dual-hosted git repository.
juzhiyuan 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 9cf91b7 feat: Support duplicate one existing Route (#1558)
9cf91b7 is described below
commit 9cf91b756f33cbddeac1adb912177f5b7762def6
Author: batman-ezio <80...@users.noreply.github.com>
AuthorDate: Fri Apr 2 10:08:34 2021 +0800
feat: Support duplicate one existing Route (#1558)
---
.gitignore | 8 ++++
web/config/routes.ts | 4 ++
... => create-edit-duplicate-delete-route.spec.js} | 45 +++++++++++++++++++---
web/src/locales/en-US/component.ts | 1 +
web/src/locales/zh-CN/component.ts | 1 +
web/src/pages/Route/Create.tsx | 10 ++---
web/src/pages/Route/List.tsx | 3 ++
7 files changed, 62 insertions(+), 10 deletions(-)
diff --git a/.gitignore b/.gitignore
index ff01226..34a1868 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,3 +57,11 @@ web/.nyc_output
web/coverage
web/cypress/screenshots/
web/cypress/videos/
+web/cypress/downloads/
+web/cypress/screenshots/
+web/cypress/videos/
+
+# vim
+*.swp
+*.swo
+
diff --git a/web/config/routes.ts b/web/config/routes.ts
index 7f01bc3..72057b5 100644
--- a/web/config/routes.ts
+++ b/web/config/routes.ts
@@ -40,6 +40,10 @@ const routes = [
component: './Route/Create',
},
{
+ path: '/routes/:rid/duplicate',
+ component: './Route/Create',
+ },
+ {
path: '/ssl/:id/edit',
component: './SSL/Create',
},
diff --git a/web/cypress/integration/route/create-edit-delete-route.spec.js b/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js
similarity index 79%
rename from web/cypress/integration/route/create-edit-delete-route.spec.js
rename to web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js
index 744e54d..85aad6f 100644
--- a/web/cypress/integration/route/create-edit-delete-route.spec.js
+++ b/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js
@@ -19,6 +19,7 @@
context('Create and Delete Route', () => {
const name = `routeName${new Date().valueOf()}`;
const newName = `newName${new Date().valueOf()}`;
+ const duplicateNewName = `duplicateName${new Date().valueOf()}`;
const sleepTime = 100;
const timeout = 5000;
@@ -153,12 +154,46 @@ context('Create and Delete Route', () => {
});
});
- it('should delete the route', function () {
- cy.visit('/routes/list');
+
+ it('should duplicate the route', function () {
+ cy.visit('/');
+ cy.contains('Route').click();
+
cy.get(this.domSelector.nameSelector).type(newName);
cy.contains('Search').click();
- cy.contains(newName).siblings().contains('Delete').click();
- cy.contains('button', 'Confirm').click();
- cy.get(this.domSelector.notification).should('contain', this.data.deleteRouteSuccess);
+ cy.contains(newName).siblings().contains('Duplicate').click();
+
+ cy.get(this.domSelector.name).clear().type(duplicateNewName);
+ cy.get(this.domSelector.description).clear().type(this.data.description2);
+ cy.contains('Next').click();
+ cy.contains('Next').click();
+ cy.contains('Next').click();
+ cy.contains('Submit').click();
+ cy.contains(this.data.submitSuccess);
+ cy.contains('Goto List').click();
+ cy.url().should('contains', 'routes/list');
+ cy.contains(duplicateNewName).siblings().should('contain', this.data.description2);
+
+ // test view
+ cy.contains(duplicateNewName).siblings().contains('View').click();
+ cy.get(this.domSelector.drawer).should('be.visible');
+
+ cy.get(this.domSelector.codemirrorScroll).within(() => {
+ cy.contains('upstream').should("exist");
+ cy.contains(duplicateNewName).should('exist');
+ });
+ });
+
+ it('should delete the route', function () {
+ cy.visit('/routes/list');
+ const { domSelector, data } = this;
+ const routeNames = [newName, duplicateNewName];
+ routeNames.forEach(function (routeName) {
+ cy.get(domSelector.name).clear().type(routeName);
+ cy.contains('Search').click();
+ cy.contains(routeName).siblings().contains('Delete').click();
+ cy.contains('button', 'Confirm').click();
+ cy.get(domSelector.notification).should('contain', data.deleteRouteSuccess);
+ });
});
});
diff --git a/web/src/locales/en-US/component.ts b/web/src/locales/en-US/component.ts
index 061ce40..a6a4100 100644
--- a/web/src/locales/en-US/component.ts
+++ b/web/src/locales/en-US/component.ts
@@ -35,6 +35,7 @@ export default {
'component.global.save': 'Save',
'component.global.edit': 'Configure',
'component.global.view': 'View',
+ 'component.global.duplicate': 'Duplicate',
'component.global.manage': 'Manage',
'component.global.update': 'Update',
'component.global.get': 'Get',
diff --git a/web/src/locales/zh-CN/component.ts b/web/src/locales/zh-CN/component.ts
index 190c51e..4cb43cf 100644
--- a/web/src/locales/zh-CN/component.ts
+++ b/web/src/locales/zh-CN/component.ts
@@ -37,6 +37,7 @@ export default {
'component.global.save': '保存',
'component.global.edit': '配置',
'component.global.view': '查看',
+ 'component.global.duplicate': '复制',
'component.global.manage': '管理',
'component.global.update': '更新',
'component.global.get': '获取',
diff --git a/web/src/pages/Route/Create.tsx b/web/src/pages/Route/Create.tsx
index 30bb210..648546f 100644
--- a/web/src/pages/Route/Create.tsx
+++ b/web/src/pages/Route/Create.tsx
@@ -88,7 +88,7 @@ const Page: React.FC<Props> = (props) => {
};
useEffect(() => {
- if (props.route.path.indexOf('edit') !== -1) {
+ if (props.route.path.indexOf('edit') !== -1 || props.route.path.indexOf('duplicate') !== -1) {
setupRoute(props.match.params.rid);
} else {
onReset();
@@ -233,7 +233,7 @@ const Page: React.FC<Props> = (props) => {
redirectOption === 'forceHttps' && filterHosts.length !== 0
? checkHostWithSSL(hosts)
: Promise.resolve(),
- checkUniqueName(value.name, (props as any).match.params.rid || ''),
+ checkUniqueName(value.name, props.route.path.indexOf('edit') > 0 ? (props as any).match.params.rid : ''),
]).then(() => {
setStep(nextStep);
});
@@ -269,9 +269,9 @@ const Page: React.FC<Props> = (props) => {
return (
<>
<PageHeaderWrapper
- title={(props as any).match.params.rid
- ? formatMessage({ id: 'page.route.editRoute' })
- : formatMessage({ id: 'page.route.createRoute' })}
+ title={`${
+ formatMessage({ id: `component.global.${props.route.path.split('/').slice(-1)[0]}`})
+ } ${formatMessage({ id: 'menu.routes' })}`}
>
<Card bordered={false}>
<Steps current={step - 1} className={styles.steps}>
diff --git a/web/src/pages/Route/List.tsx b/web/src/pages/Route/List.tsx
index dc5c3d3..a9c1ba5 100644
--- a/web/src/pages/Route/List.tsx
+++ b/web/src/pages/Route/List.tsx
@@ -417,6 +417,9 @@ const Page: React.FC = () => {
}}>
{formatMessage({ id: 'component.global.view' })}
</Button>
+ <Button type="primary" onClick={() => history.push(`/routes/${record.id}/duplicate`)}>
+ {formatMessage({ id: 'component.global.duplicate' })}
+ </Button>
<Popconfirm
title={formatMessage({ id: 'component.global.popconfirm.title.delete' })}
onConfirm={() => {