diff --git a/web/cypress/integration/consumer/table-auto-jump-when-no-data.spec.js b/web/cypress/integration/consumer/table-auto-jump-when-no-data.spec.js new file mode 100644 index 0000000000..209a540cbc --- /dev/null +++ b/web/cypress/integration/consumer/table-auto-jump-when-no-data.spec.js @@ -0,0 +1,82 @@ +/* + * 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. + */ + +context('Table Auto Jump When No Data', () => { + const selector = { + username: '#username', + page_item: '.ant-pagination-item-2', + deleteAlert: '.ant-modal-body', + notificationCloseIcon: '.ant-notification-close-icon', + notification: '.ant-notification-notice-message', + table_row: '.ant-table-row', + pluginCard: '.ant-card', + drawer: '.ant-drawer-content', + monacoScroll: '.monaco-scrollable-element', + monacoViewZones: '.view-zones', + disabledSwitcher: '#disable', + popoper: '.ant-popover', + popoprerHiden: '.ant-popover-hidden', + }; + + const data = { + consumerName: 'test_consumer', + createConsumerSuccess: 'Create Consumer Successfully', + deleteConsumerSuccess: 'Delete Consumer Successfully', + }; + + before(() => { + cy.login().then(() => { + Array.from({ length: 11 }).forEach((value, key) => { + const payload = { + username: data.consumerName + key, + plugins: { + 'key-auth': { + key: 'test', + disable: false, + }, + }, + }; + cy.requestWithToken({ method: 'PUT', payload, url: '/apisix/admin/consumers' }); + }); + }); + }); + + it('should delete last data and jump to first page', () => { + cy.visit('/'); + cy.contains('Consumer').click(); + cy.get(selector.page_item).click(); + cy.wait(1000); + cy.contains('Delete').click(); + cy.get(selector.popoper) + .not(selector.popoprerHiden) + .contains('Confirm') + .should('be.visible') + .click(); + cy.get(selector.notification).should('contain', data.deleteConsumerSuccess); + cy.get(selector.notificationCloseIcon).click(); + cy.url().should('contains', '/consumer/list?page=1&pageSize=10'); + cy.get(selector.table_row).should((consumer) => { + expect(consumer).to.have.length(10); + }); + cy.get(`.ant-table-cell:contains(${data.consumerName})`).each((elem) => { + cy.requestWithToken({ + method: 'DELETE', + url: `/apisix/admin/consumers/${elem.text()}`, + }); + }); + }); +}); diff --git a/web/cypress/integration/proto/create_and_edit_and_delete_proto.spce.js b/web/cypress/integration/proto/create_and_edit_and_delete_proto.spec.js similarity index 97% rename from web/cypress/integration/proto/create_and_edit_and_delete_proto.spce.js rename to web/cypress/integration/proto/create_and_edit_and_delete_proto.spec.js index 7443aa86d6..bad768622d 100644 --- a/web/cypress/integration/proto/create_and_edit_and_delete_proto.spce.js +++ b/web/cypress/integration/proto/create_and_edit_and_delete_proto.spec.js @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* eslint-disable no-undef */ context('Create and Delete Proto', () => { const selector = { @@ -41,7 +40,7 @@ optional string email = 3; }`, createProtoSuccess: 'Create proto Successfully', configureProtoSuccess: 'Configure proto Successfully', - deleteProtoSuccess: 'Delete Upstream Successfully', + deleteProtoSuccess: 'Delete proto Successfully', }; beforeEach(() => { diff --git a/web/cypress/integration/proto/table-auto-jump-when-no-data.spec.js b/web/cypress/integration/proto/table-auto-jump-when-no-data.spec.js new file mode 100644 index 0000000000..d81d862a64 --- /dev/null +++ b/web/cypress/integration/proto/table-auto-jump-when-no-data.spec.js @@ -0,0 +1,68 @@ +/* + * 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. + */ + +context('Batch Create Proto And Delete Proto', () => { + const selector = { + id: '#id', + content: '.view-lines', + page_item: '.ant-pagination-item-2', + draw: '.ant-drawer-content', + deleteAlert: '.ant-modal-body', + notificationCloseIcon: '.ant-notification-close-icon', + notification: '.ant-notification-notice-message', + table_row: '.ant-table-row', + }; + + const data = { + createProtoSuccess: 'Create proto Successfully', + deleteProtoSuccess: 'Delete proto Successfully', + }; + + before(() => { + cy.login().then(() => { + Array.from({ length: 11 }).forEach(async (value, key) => { + const payload = { + content: 'test', + desc: '', + id: `protoId${key}`, + }; + cy.requestWithToken({ method: 'POST', payload, url: '/apisix/admin/proto' }); + }); + }); + }); + + it('should delete last data and jump to first page', () => { + cy.visit('/'); + cy.contains('Protocol Buffers').click(); + cy.get(selector.page_item).click(); + cy.wait(1000); + cy.contains('Delete').click(); + cy.contains('button', 'Confirm').click(); + cy.get(selector.notification).should('contain', data.deleteProtoSuccess); + cy.get(selector.notificationCloseIcon).click(); + cy.url().should('contains', '/proto/list?page=1&pageSize=10'); + cy.get(selector.table_row).should((proto) => { + expect(proto).to.have.length(10); + }); + cy.get('.ant-table-cell:contains(protoId)').each((elem) => { + cy.requestWithToken({ + method: 'DELETE', + url: `/apisix/admin/proto/${elem.text()}`, + }); + }); + }); +}); diff --git a/web/cypress/integration/route/table-auto-jump-when-no-data.spec.js b/web/cypress/integration/route/table-auto-jump-when-no-data.spec.js new file mode 100644 index 0000000000..5f0a12569e --- /dev/null +++ b/web/cypress/integration/route/table-auto-jump-when-no-data.spec.js @@ -0,0 +1,94 @@ +/* + * 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. + */ + +context('Table Auto Jump When No Data', () => { + const selector = { + name: '#name', + nodes_0_host: '#submitNodes_0_host', + page_item: '.ant-pagination-item-2', + deleteAlert: '.ant-modal-body', + notificationCloseIcon: '.ant-notification-close-icon', + notification: '.ant-notification-notice-message', + table_row: '.ant-table-row', + }; + + const data = { + submitSuccess: 'Submit Successfully', + deleteRouteSuccess: 'Delete Route Successfully', + }; + + before(() => { + cy.login().then(() => { + Array.from({ length: 11 }).forEach((value, key) => { + const payload = { + methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS', 'CONNECT', 'TRACE'], + priority: 0, + name: `routeName${key}`, + desc: '', + status: 1, + labels: {}, + uri: '/*', + upstream: { + type: 'roundrobin', + pass_host: 'pass', + scheme: 'http', + timeout: { + connect: 6, + send: 6, + read: 6, + }, + keepalive_pool: { + size: 320, + idle_timeout: 60, + requests: 1000, + }, + nodes: { + '127.0.0.1': 1, + }, + }, + }; + cy.requestWithToken({ method: 'POST', payload, url: '/apisix/admin/routes' }); + }); + }); + }); + + it('should delete last data and jump to first page', () => { + cy.visit('/'); + cy.contains('Route').click(); + cy.get(selector.page_item).click(); + cy.wait(1000); + cy.contains('routeName').siblings().contains('More').click(); + cy.contains('Delete').click(); + cy.get(selector.deleteAlert) + .should('be.visible') + .within(() => { + cy.contains('OK').click(); + }); + cy.get(selector.notification).should('contain', data.deleteRouteSuccess); + cy.get(selector.notificationCloseIcon).click(); + cy.url().should('contains', '/routes/list?page=1&pageSize=10'); + cy.get(selector.table_row).should((route) => { + expect(route).to.have.length(10); + }); + cy.get('.ant-table-cell:contains(routeName)').each((elem) => { + cy.requestWithToken({ + method: 'DELETE', + url: `/apisix/admin/routes/${elem.next().text()}`, + }); + }); + }); +}); diff --git a/web/cypress/integration/service/table-auto-jump-when-no-data.spec.js b/web/cypress/integration/service/table-auto-jump-when-no-data.spec.js new file mode 100644 index 0000000000..98f9eb80c0 --- /dev/null +++ b/web/cypress/integration/service/table-auto-jump-when-no-data.spec.js @@ -0,0 +1,85 @@ +/* + * 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. + */ +/* eslint-disable no-undef */ + +context('Table Auto Jump When No Data', () => { + const selector = { + name: '#name', + nodes_0_host: '#submitNodes_0_host', + page_item: '.ant-pagination-item-2', + deleteAlert: '.ant-modal-body', + notificationCloseIcon: '.ant-notification-close-icon', + notification: '.ant-notification-notice-message', + table_row: '.ant-table-row', + }; + + const data = { + createServiceSuccess: 'Create Service Successfully', + deleteServiceSuccess: 'Delete Service Successfully', + }; + + beforeEach(() => { + cy.login().then(() => { + Array.from({ length: 11 }).forEach((value, key) => { + const payload = { + name: `serviceName${key}`, + plugins: {}, + upstream: { + type: 'roundrobin', + pass_host: 'pass', + scheme: 'http', + timeout: { + connect: 6, + send: 6, + read: 6, + }, + keepalive_pool: { + size: 320, + idle_timeout: 60, + requests: 1000, + }, + nodes: { + '127.0.0.1': 1, + }, + }, + }; + cy.requestWithToken({ method: 'POST', payload, url: '/apisix/admin/services' }); + }); + }); + }); + + it('should delete last data and jump to first page', () => { + cy.visit('/'); + cy.contains('Service').click(); + cy.get(selector.page_item).click(); + cy.wait(1000); + cy.contains('serviceName').siblings().contains('Delete').click(); + cy.contains('button', 'Confirm').click(); + cy.get(selector.notification).should('contain', data.deleteServiceSuccess); + cy.get(selector.notificationCloseIcon).click(); + cy.url().should('contains', '/service/list?page=1&pageSize=10'); + cy.get(selector.table_row).should((service) => { + expect(service).to.have.length(10); + }); + cy.get('.ant-table-cell:contains(serviceName)').each((elem) => { + cy.requestWithToken({ + method: 'DELETE', + url: `/apisix/admin/services/${elem.prev().text()}`, + }); + }); + }); +}); diff --git a/web/cypress/integration/upstream/table-auto-jump-when-no-data.spec.js b/web/cypress/integration/upstream/table-auto-jump-when-no-data.spec.js new file mode 100644 index 0000000000..bc80371364 --- /dev/null +++ b/web/cypress/integration/upstream/table-auto-jump-when-no-data.spec.js @@ -0,0 +1,83 @@ +/* + * 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. + */ +/* eslint-disable no-undef */ + +context('Table Auto Jump When No Data', () => { + const selector = { + id: '#id', + name: '#name', + nodes_0_host: '#submitNodes_0_host', + page_item: '.ant-pagination-item-2', + deleteAlert: '.ant-modal-body', + notificationCloseIcon: '.ant-notification-close-icon', + notification: '.ant-notification-notice-message', + table_row: ' .ant-table-row', + }; + + const data = { + createUpstreamSuccess: 'Create Upstream Successfully', + deleteUpstreamSuccess: 'Delete Upstream Successfully', + }; + + beforeEach(() => { + cy.login().then(() => { + Array.from({ length: 11 }).forEach((value, key) => { + const payload = { + name: `upstreamName${key}`, + type: 'roundrobin', + pass_host: 'pass', + scheme: 'http', + timeout: { + connect: 6, + send: 6, + read: 6, + }, + keepalive_pool: { + size: 320, + idle_timeout: 60, + requests: 1000, + }, + nodes: { + '127.0.0.1': 1, + }, + }; + cy.requestWithToken({ method: 'POST', payload, url: `/apisix/admin/upstreams` }); + }); + }); + }); + + it('should delete the upstream', () => { + cy.visit('/'); + cy.contains('Upstream').click(); + cy.get(selector.page_item).click(); + cy.wait(1000); + cy.contains('upstreamName').siblings().contains('Delete').click(); + cy.contains('button', 'Confirm').click(); + cy.get(selector.notification).should('contain', data.deleteUpstreamSuccess); + cy.get('.ant-notification-close-x').click(); + cy.url().should('contains', '/upstream/list?page=1&pageSize=10'); + cy.get(selector.table_row).should((upstream) => { + expect(upstream).to.have.length(10); + }); + cy.get('.ant-table-cell:contains(upstreamName)').each((elem) => { + cy.requestWithToken({ + method: 'DELETE', + url: `/apisix/admin/upstreams/${elem.prev().text()}`, + }); + }); + }); +}); diff --git a/web/cypress/support/commands.js b/web/cypress/support/commands.js index 990288a88b..0a7ae8c7d3 100644 --- a/web/cypress/support/commands.js +++ b/web/cypress/support/commands.js @@ -143,3 +143,17 @@ Cypress.Commands.add('configurePlugin', ({ name, cases }) => { } }); }); + +Cypress.Commands.add('requestWithToken', ({ method, url, payload }) => { + const { SERVE_ENV = 'dev' } = Cypress.env(); + // Make sure the request is synchronous + cy.request({ + method, + url: defaultSettings.serveUrlMap[SERVE_ENV] + url, + body: payload, + headers: { Authorization: localStorage.getItem('token') }, + }).then((res) => { + expect(res.body.code).to.equal(0); + return res; + }); +}); diff --git a/web/src/hooks/usePagination.ts b/web/src/hooks/usePagination.ts index 41938c705e..c6b1a02d22 100644 --- a/web/src/hooks/usePagination.ts +++ b/web/src/hooks/usePagination.ts @@ -17,6 +17,9 @@ import { useEffect, useState } from 'react'; import { useLocation, history } from 'umi'; import querystring from 'query-string'; +import type { PageInfo } from '@ant-design/pro-table/lib/typing'; +import type { ActionType } from '@ant-design/pro-table'; +import type { MutableRefObject } from 'react'; export default function usePagination() { const location = useLocation(); @@ -30,5 +33,14 @@ export default function usePagination() { history.replace(`${location.pathname}?page=${page}&pageSize=${pageSize}`); }; - return { paginationConfig, savePageList }; + const checkPageList = (ref: MutableRefObject) => { + const { current, pageSize, total } = ref.current?.pageInfo as PageInfo; + if (current > pageSize / total && current > 1) { + savePageList(paginationConfig.current - 1, paginationConfig.pageSize); + } else { + ref.current?.reload(); + } + }; + + return { paginationConfig, savePageList, checkPageList }; } diff --git a/web/src/pages/Consumer/List.tsx b/web/src/pages/Consumer/List.tsx index 3326a33d34..912ef8a00a 100644 --- a/web/src/pages/Consumer/List.tsx +++ b/web/src/pages/Consumer/List.tsx @@ -37,7 +37,7 @@ const Page: React.FC = () => { const [rawData, setRawData] = useState>({}); const [id, setId] = useState(''); const [editorMode, setEditorMode] = useState<'create' | 'update'>('create'); - const { paginationConfig, savePageList } = usePagination(); + const { paginationConfig, savePageList, checkPageList } = usePagination(); const columns: ProColumns[] = [ { @@ -91,8 +91,7 @@ const Page: React.FC = () => { id: 'menu.consumer', })} ${formatMessage({ id: 'component.status.success' })}`, }); - /* eslint-disable no-unused-expressions */ - ref.current?.reload(); + checkPageList(ref); }); }} > diff --git a/web/src/pages/Plugin/List.tsx b/web/src/pages/Plugin/List.tsx index c9b4a93316..7d9be5db44 100644 --- a/web/src/pages/Plugin/List.tsx +++ b/web/src/pages/Plugin/List.tsx @@ -35,7 +35,7 @@ const Page: React.FC = () => { const [initialData, setInitialData] = useState({}); const [pluginList, setPluginList] = useState([]); const [name, setName] = useState(''); - const { paginationConfig, savePageList } = usePagination(); + const { paginationConfig, savePageList, checkPageList } = usePagination(); useEffect(() => { fetchPluginList().then(setPluginList); @@ -85,7 +85,7 @@ const Page: React.FC = () => { id: 'menu.plugin', })} ${formatMessage({ id: 'component.status.success' })}`, }); - ref.current?.reload(); + checkPageList(ref); setInitialData(plugins); setName(''); }); diff --git a/web/src/pages/Proto/List.tsx b/web/src/pages/Proto/List.tsx index b4c80da396..07f344e886 100755 --- a/web/src/pages/Proto/List.tsx +++ b/web/src/pages/Proto/List.tsx @@ -16,7 +16,8 @@ */ import React, { useRef, useState } from 'react'; import { PageHeaderWrapper } from '@ant-design/pro-layout'; -import ProTable, { ProColumns, ActionType } from '@ant-design/pro-table'; +import type { ProColumns, ActionType } from '@ant-design/pro-table'; +import ProTable from '@ant-design/pro-table'; import ProtoDrawer from './components/ProtoDrawer'; import { Button, notification, Popconfirm, Space } from 'antd'; import { useIntl } from 'umi'; @@ -31,7 +32,7 @@ const Page: React.FC = () => { const ref = useRef(); const { formatMessage } = useIntl(); const [drawerVisible, setDrawerVisible] = useState(false); - const { paginationConfig, savePageList } = usePagination(); + const { paginationConfig, savePageList, checkPageList } = usePagination(); const emptyProtoData = { id: null, content: '', @@ -92,21 +93,20 @@ const Page: React.FC = () => { {formatMessage({ id: 'component.global.edit' })} { remove(record.id).then(() => { notification.success({ - message: formatMessage({ id: 'page.upstream.list.delete.successfully' }), + message: formatMessage({ id: 'page.proto.list.delete.successfully' }), }); - /* eslint-disable no-unused-expressions */ - ref.current?.reload(); + checkPageList(ref); }); }} > diff --git a/web/src/pages/Proto/locales/en-US.ts b/web/src/pages/Proto/locales/en-US.ts index 69074cc51d..13f1f1f7d8 100644 --- a/web/src/pages/Proto/locales/en-US.ts +++ b/web/src/pages/Proto/locales/en-US.ts @@ -18,7 +18,12 @@ export default { 'page.proto.list': 'Proto List', 'page.proto.list.description': "Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data.You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.The protocol buffers list contains the created proto files. When the grpc transcode plug-in is enabled, the ID can be configured to read the contents of the corresponding proto files.", - + 'page.proto.list.edit': 'Configure', + 'page.proto.list.confirm.delete': 'Are you sure to delete ?', + 'page.proto.list.confirm': 'Confirm', + 'page.proto.list.cancel': 'Cancel', + 'page.proto.list.delete.successfully': 'Delete proto Successfully', + 'page.proto.list.delete': 'Delete', 'page.proto.id.tooltip': ".proto file's id", 'page.proto.desc': 'description', @@ -31,4 +36,5 @@ export default { 'page.proto.drawer.edit': 'Configure proto', 'page.proto.drawer.create.successfully': 'Create proto Successfully', 'page.proto.drawer.edit.successfully': 'Configure proto Successfully', + 'page.proto.drawer.delete.successfully': 'Delete proto Successfully', }; diff --git a/web/src/pages/Proto/locales/zh-CN.ts b/web/src/pages/Proto/locales/zh-CN.ts index 2fe11235cb..ac68d8c08f 100644 --- a/web/src/pages/Proto/locales/zh-CN.ts +++ b/web/src/pages/Proto/locales/zh-CN.ts @@ -18,6 +18,12 @@ export default { 'page.proto.list': 'Proto 列表', 'page.proto.list.description': 'Protocol Buffers 是 Google 用于序列化结构化数据的框架,它具有语言中立、平台中立、可扩展机制的特性,您只需定义一次数据的结构化方式,然后就可以使用各种语言通过特殊生成的源代码轻松地将结构化数据写入和读取各种数据流。Protocol Buffers 列表包含了已创建的 proto 文件,在启用 grpc-transcode 插件时可配置 ID 读取对应的 proto 文件内容。', + 'page.proto.list.edit': '配置', + 'page.proto.list.confirm.delete': '确定删除该条记录吗?', + 'page.proto.list.confirm': '确定', + 'page.proto.list.cancel': '取消', + 'page.proto.list.delete.successfully': '删除记录成功', + 'page.proto.list.delete': '删除', 'page.proto.id.tooltip': '.proto 文件的 id', @@ -30,5 +36,6 @@ export default { 'page.proto.drawer.create': '创建 proto', 'page.proto.drawer.edit': '配置 proto', 'page.proto.drawer.create.successfully': '创建 proto 成功', - 'page.proto.drawer.edit.successfully': '配置 proto', + 'page.proto.drawer.edit.successfully': '配置 proto 成功', + 'page.proto.drawer.delete.successfully': '删除 proto 成功', }; diff --git a/web/src/pages/Route/List.tsx b/web/src/pages/Route/List.tsx index 1e1760f311..3b06a995d9 100755 --- a/web/src/pages/Route/List.tsx +++ b/web/src/pages/Route/List.tsx @@ -87,7 +87,7 @@ const Page: React.FC = () => { const [rawData, setRawData] = useState>({}); const [id, setId] = useState(''); const [editorMode, setEditorMode] = useState<'create' | 'update'>('create'); - const { paginationConfig, savePageList } = usePagination(); + const { paginationConfig, savePageList, checkPageList } = usePagination(); const [debugDrawVisible, setDebugDrawVisible] = useState(false); useEffect(() => { @@ -107,7 +107,7 @@ const Page: React.FC = () => { message: msgTip, }); - ref.current?.reload(); + checkPageList(ref); }; const handlePublishOffline = (rid: string, status: RouteModule.RouteStatus) => { @@ -228,47 +228,47 @@ const Page: React.FC = () => { onClick: () => void; icon?: ReactNode; }[] = [ - { - name: formatMessage({ id: 'component.global.view' }), - onClick: () => { - setId(record.id); - setRawData(omit(record, DELETE_FIELDS)); - setVisible(true); - setEditorMode('update'); + { + name: formatMessage({ id: 'component.global.view' }), + onClick: () => { + setId(record.id); + setRawData(omit(record, DELETE_FIELDS)); + setVisible(true); + setEditorMode('update'); + }, }, - }, - { - name: formatMessage({ id: 'component.global.duplicate' }), - onClick: () => { - history.push(`/routes/${record.id}/duplicate`); + { + name: formatMessage({ id: 'component.global.duplicate' }), + onClick: () => { + history.push(`/routes/${record.id}/duplicate`); + }, }, - }, - { - name: formatMessage({ id: 'component.global.delete' }), - onClick: () => { - Modal.confirm({ - type: 'warning', - title: formatMessage({ id: 'component.global.popconfirm.title.delete' }), - content: ( - <> - {formatMessage({ id: 'component.global.name' })} - {record.name} -
- ID - {record.id} - - ), - onOk: () => { - return remove(record.id!).then(() => { - handleTableActionSuccessResponse( - `${formatMessage({ id: 'component.global.delete' })} ${formatMessage({ - id: 'menu.routes', - })} ${formatMessage({ id: 'component.status.success' })}`, - ); - }); - }, - }); + { + name: formatMessage({ id: 'component.global.delete' }), + onClick: () => { + Modal.confirm({ + type: 'warning', + title: formatMessage({ id: 'component.global.popconfirm.title.delete' }), + content: ( + <> + {formatMessage({ id: 'component.global.name' })} - {record.name} +
+ ID - {record.id} + + ), + onOk: () => { + return remove(record.id!).then(() => { + handleTableActionSuccessResponse( + `${formatMessage({ id: 'component.global.delete' })} ${formatMessage({ + id: 'menu.routes', + })} ${formatMessage({ id: 'component.status.success' })}`, + ); + }); + }, + }); + }, }, - }, - ]; + ]; return ( { const tableRef = useRef(); const { formatMessage } = useIntl(); - const { paginationConfig, savePageList } = usePagination(); + const { paginationConfig, savePageList, checkPageList } = usePagination(); const columns: ProColumns[] = [ { @@ -75,8 +75,7 @@ const Page: React.FC = () => { notification.success({ message: formatMessage({ id: 'component.ssl.removeSSLSuccess' }), }); - /* eslint-disable no-unused-expressions */ - requestAnimationFrame(() => tableRef.current?.reload()); + requestAnimationFrame(() => checkPageList(tableRef)); }) } cancelText={formatMessage({ id: 'component.global.cancel' })} diff --git a/web/src/pages/Service/List.tsx b/web/src/pages/Service/List.tsx index 0946a4b1f0..948f112709 100644 --- a/web/src/pages/Service/List.tsx +++ b/web/src/pages/Service/List.tsx @@ -35,7 +35,7 @@ const Page: React.FC = () => { const [rawData, setRawData] = useState>({}); const [id, setId] = useState(''); const [editorMode, setEditorMode] = useState<'create' | 'update'>('create'); - const { paginationConfig, savePageList } = usePagination(); + const { paginationConfig, savePageList, checkPageList } = usePagination(); const columns: ProColumns[] = [ { @@ -82,8 +82,7 @@ const Page: React.FC = () => { id: 'menu.service', })} ${formatMessage({ id: 'component.status.success' })}`, }); - /* eslint-disable no-unused-expressions */ - ref.current?.reload(); + checkPageList(ref); }); }} okText={formatMessage({ id: 'component.global.confirm' })} diff --git a/web/src/pages/Upstream/List.tsx b/web/src/pages/Upstream/List.tsx index 5d6931338b..c0348743e0 100644 --- a/web/src/pages/Upstream/List.tsx +++ b/web/src/pages/Upstream/List.tsx @@ -37,7 +37,7 @@ const Page: React.FC = () => { const [rawData, setRawData] = useState>({}); const [id, setId] = useState(''); const [editorMode, setEditorMode] = useState<'create' | 'update'>('create'); - const { paginationConfig, savePageList } = usePagination(); + const { paginationConfig, savePageList, checkPageList } = usePagination(); const { formatMessage } = useIntl(); const columns: ProColumns[] = [ @@ -95,8 +95,7 @@ const Page: React.FC = () => { notification.success({ message: formatMessage({ id: 'page.upstream.list.delete.successfully' }), }); - /* eslint-disable no-unused-expressions */ - ref.current?.reload(); + checkPageList(ref); }); }} >