From af855915896562c488c2b4669e24883cd140cfb5 Mon Sep 17 00:00:00 2001 From: Baoyuan Date: Thu, 5 Aug 2021 23:22:57 -0500 Subject: [PATCH] run prettier on whole project (#2039) --- web/config/config.ts | 11 +- web/cypress/fixtures/plugin-dataset.json | 4 +- .../fixtures/rawDataEditor-dataset.json | 14 +- web/cypress/fixtures/route-json-data.json | 12 +- ...sumer-with-api-breaker-plugin-form.spec.js | 13 +- ...sumer-with-limit-count-plugin-form.spec.js | 10 +- ...te-consumer-with-proxy-mirror-form.spec.js | 9 +- .../create-upstream-with-cors-form.spec.js | 11 +- ...reate-upstream-with-limit-req-form.spec.js | 9 +- .../create-with-limit-conn-form.spec.js | 9 +- ...eate-with-referer-restriction-form.spec.js | 13 +- .../create_and_delete_consumer.spec.js | 13 +- .../dashboard/dashboard-smoketest.spec.js | 2 +- .../integration/lang/switch-language.spec.js | 2 +- .../create-delete-in-drawer-plugin.spec.js | 70 ++-- .../plugin/create-edit-delete-plugin.spec.js | 16 +- ...create-edit-delete-plugin-template.spec.js | 1 - .../rawDataEditor/test-rawDataEditor.spec.js | 4 +- .../check-route-required-field-flag.spec.js | 34 +- ...create-edit-duplicate-delete-route.spec.js | 10 +- ...te-edit-route-with-redirect-plugin.spec.js | 15 +- ...e-route-when-not-select-upsteam-id.spec.js | 1 - .../create-route-with-chash-upstream.spec.js | 6 +- .../route/create-route-with-cors-form.spec.js | 67 ++-- ...route-with-limit-count-plugin-form.spec.js | 2 +- .../integration/route/search-route.spec.js | 4 +- .../create-edit-delete-service.spec.js | 2 +- ...create-service-with-chash-upstream.spec.js | 5 +- .../create_and_delete_upstream.spec.js | 49 ++- ...dit_upstream_with_custom_chash_key.spec.js | 4 +- web/cypress/support/commands.js | 46 +-- .../components/LabelsfDrawer/LabelsDrawer.tsx | 10 +- web/src/components/PanelSection/index.tsx | 6 +- web/src/components/Plugin/PluginDetail.tsx | 121 ++++--- web/src/components/Plugin/PluginPage.tsx | 55 ++- web/src/components/Plugin/UI/api-breaker.tsx | 50 +-- web/src/components/Plugin/UI/basic-auth.tsx | 21 +- web/src/components/Plugin/UI/cors.tsx | 49 +-- web/src/components/Plugin/UI/limit-conn.tsx | 27 +- web/src/components/Plugin/UI/limit-count.tsx | 210 +++++++---- web/src/components/Plugin/UI/limit-req.tsx | 50 ++- web/src/components/Plugin/UI/plugin.tsx | 49 ++- web/src/components/Plugin/UI/proxy-mirror.tsx | 16 +- .../Plugin/UI/referer-restriction.tsx | 58 +-- web/src/components/Plugin/data.tsx | 206 +++++------ web/src/components/Plugin/locales/en-US.ts | 113 ++++-- web/src/components/Plugin/locales/zh-CN.ts | 98 +++-- web/src/components/Plugin/service.ts | 34 +- web/src/components/Plugin/typing.d.ts | 4 +- web/src/components/PluginFlow/PluginFlow.tsx | 215 ++++++----- .../components/FlowGraph/FlowGraph.ts | 342 ++++++++++-------- .../PluginFlow/components/FlowGraph/index.ts | 2 +- .../PluginFlow/components/FlowGraph/shapes.ts | 23 +- .../PluginFlow/components/Toolbar/index.tsx | 168 ++++----- web/src/components/PluginFlow/constants.ts | 71 ++-- web/src/components/PluginFlow/index.ts | 2 +- .../components/PluginFlow/locales/en-US.ts | 16 +- .../components/PluginFlow/locales/zh-CN.ts | 4 +- .../RawDataEditor/RawDataEditor.tsx | 124 ++++--- web/src/components/Upstream/UpstreamForm.tsx | 166 +++++---- .../Upstream/components/DiscoveryType.tsx | 27 +- .../components/Upstream/components/Nodes.tsx | 46 ++- .../Upstream/components/PassHost.tsx | 70 ++-- .../Upstream/components/Retries.tsx | 22 +- .../components/Upstream/components/Scheme.tsx | 49 +-- .../Upstream/components/ServiceName.tsx | 27 +- .../components/Upstream/components/TLS.tsx | 101 +++--- .../Upstream/components/TimeUnit.tsx | 4 +- .../Upstream/components/Timeout.tsx | 16 +- .../components/Upstream/components/Type.tsx | 51 ++- .../Upstream/components/UpstreamSelector.tsx | 26 +- .../components/active-check/Concurrency.tsx | 23 +- .../active-check/Healthy/HttpStatuses.tsx | 30 +- .../active-check/Healthy/Interval.tsx | 24 +- .../active-check/Healthy/Successes.tsx | 26 +- .../components/active-check/Healthy/index.ts | 10 +- .../Upstream/components/active-check/Host.tsx | 23 +- .../components/active-check/HttpPath.tsx | 28 +- .../active-check/HttpsVerifyCertificate.tsx | 26 +- .../Upstream/components/active-check/Port.tsx | 18 +- .../components/active-check/ReqHeaders.tsx | 30 +- .../components/active-check/Timeout.tsx | 25 +- .../Upstream/components/active-check/Type.tsx | 47 ++- .../active-check/Unhealthy/HttpFailures.tsx | 26 +- .../active-check/Unhealthy/HttpStatuses.tsx | 27 +- .../active-check/Unhealthy/Interval.tsx | 24 +- .../active-check/Unhealthy/TCPFailures.tsx | 30 +- .../active-check/Unhealthy/Timeouts.tsx | 28 +- .../active-check/Unhealthy/index.ts | 14 +- .../Upstream/components/active-check/index.ts | 24 +- .../passive-check/Healthy/HttpStatuses.tsx | 53 ++- .../passive-check/Healthy/Successes.tsx | 26 +- .../components/passive-check/Healthy/index.ts | 8 +- .../components/passive-check/Type.tsx | 47 ++- .../passive-check/Unhealthy/HttpFailures.tsx | 26 +- .../passive-check/Unhealthy/HttpStatuses.tsx | 31 +- .../passive-check/Unhealthy/TcpFailures.tsx | 22 +- .../passive-check/Unhealthy/Timeouts.tsx | 28 +- .../passive-check/Unhealthy/index.ts | 12 +- .../components/passive-check/index.ts | 10 +- web/src/components/Upstream/constant.ts | 24 +- web/src/components/Upstream/locales/en-US.ts | 74 ++-- web/src/components/Upstream/locales/zh-CN.ts | 59 ++- web/src/components/Upstream/service.ts | 50 +-- web/src/components/Upstream/typings.d.ts | 18 +- web/src/locales/en-US.ts | 6 +- web/src/locales/en-US/component.ts | 3 +- web/src/locales/en-US/menu.ts | 2 +- web/src/locales/en-US/other.ts | 2 +- web/src/locales/zh-CN.ts | 6 +- web/src/locales/zh-CN/menu.ts | 2 +- web/src/locales/zh-CN/other.ts | 2 +- web/src/pages/Consumer/List.tsx | 51 ++- web/src/pages/Consumer/locales/en-US.ts | 5 +- web/src/pages/Consumer/locales/zh-CN.ts | 3 +- web/src/pages/PluginTemplate/Create.tsx | 39 +- web/src/pages/PluginTemplate/List.tsx | 44 +-- .../pages/PluginTemplate/components/Step1.tsx | 11 +- web/src/pages/PluginTemplate/service.ts | 8 +- web/src/pages/Route/Create.tsx | 42 ++- web/src/pages/Route/List.tsx | 173 +++++---- .../components/CreateStep4/CreateStep4.tsx | 10 +- .../components/DebugViews/DebugDrawView.tsx | 216 ++++++----- .../DebugViews/DebugFormDataView.tsx | 67 ++-- .../components/DebugViews/DebugParamsView.tsx | 17 +- .../components/Step1/MatchingRulesView.tsx | 97 ++--- .../pages/Route/components/Step1/MetaView.tsx | 148 ++++---- .../Route/components/Step1/ProxyRewrite.tsx | 154 ++++---- .../components/Step1/RequestConfigView.tsx | 53 ++- .../pages/Route/components/Step3/index.tsx | 36 +- web/src/pages/Route/constants.ts | 134 +++---- web/src/pages/Route/locales/en-US.ts | 27 +- web/src/pages/Route/locales/zh-CN.ts | 12 +- web/src/pages/Route/service.ts | 16 +- web/src/pages/Route/transform.ts | 82 +++-- web/src/pages/Route/typing.d.ts | 18 +- web/src/pages/SSL/List.tsx | 7 +- .../SSL/components/CertificateForm/index.tsx | 12 +- web/src/pages/SSL/components/Step1/index.tsx | 5 +- web/src/pages/SSL/locales/en-US.ts | 3 +- web/src/pages/SSL/locales/zh-CN.ts | 3 +- web/src/pages/ServerInfo/List.tsx | 4 +- web/src/pages/ServerInfo/service.ts | 2 +- web/src/pages/ServerInfo/typing.d.ts | 6 +- web/src/pages/Service/Create.tsx | 27 +- web/src/pages/Service/List.tsx | 53 +-- web/src/pages/Service/components/Step1.tsx | 27 +- web/src/pages/Service/locales/en-US.ts | 5 +- web/src/pages/Service/locales/zh-CN.ts | 5 +- web/src/pages/Upstream/Create.tsx | 23 +- web/src/pages/Upstream/List.tsx | 54 +-- web/src/pages/Upstream/components/Step1.tsx | 14 +- web/src/pages/Upstream/locales/en-US.ts | 28 +- web/src/pages/Upstream/locales/zh-CN.ts | 20 +- web/src/pages/Upstream/service.ts | 3 +- web/src/pages/User/Login.tsx | 5 +- .../User/components/LoginMethodPassword.tsx | 9 +- web/src/pages/User/locales/en-US.ts | 5 +- web/src/pages/User/locales/zh-CN.ts | 3 +- web/src/typings.d.ts | 11 +- 160 files changed, 3366 insertions(+), 2642 deletions(-) diff --git a/web/config/config.ts b/web/config/config.ts index dd09625e04..920a17821c 100644 --- a/web/config/config.ts +++ b/web/config/config.ts @@ -63,10 +63,11 @@ export default defineConfig({ }, outputPath: '../output/html', extraBabelPlugins: [ - ['babel-plugin-istanbul', { - "exclude": [ - "**/.umi", "**/locales" - ] - }], + [ + 'babel-plugin-istanbul', + { + exclude: ['**/.umi', '**/locales'], + }, + ], ], }); diff --git a/web/cypress/fixtures/plugin-dataset.json b/web/cypress/fixtures/plugin-dataset.json index 5f3739ad67..940f34af79 100644 --- a/web/cypress/fixtures/plugin-dataset.json +++ b/web/cypress/fixtures/plugin-dataset.json @@ -192,8 +192,8 @@ { "shouldValid": true, "data": { - "client_id" : "foo", - "token_endpoint" : "https://host.domain/auth/realms/foo/protocol/openid-connect/token" + "client_id": "foo", + "token_endpoint": "https://host.domain/auth/realms/foo/protocol/openid-connect/token" } }, { diff --git a/web/cypress/fixtures/rawDataEditor-dataset.json b/web/cypress/fixtures/rawDataEditor-dataset.json index 613322f9f0..d13c4706e2 100644 --- a/web/cypress/fixtures/rawDataEditor-dataset.json +++ b/web/cypress/fixtures/rawDataEditor-dataset.json @@ -1,18 +1,8 @@ { "Route": { - "uris": [ - "/*" - ], + "uris": ["/*"], "name": "root", - "methods": [ - "GET", - "HEAD", - "POST", - "PUT", - "DELETE", - "OPTIONS", - "PATCH" - ], + "methods": ["GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"], "upstream": { "nodes": [ { diff --git a/web/cypress/fixtures/route-json-data.json b/web/cypress/fixtures/route-json-data.json index c9ee52c2ef..2bf983205e 100644 --- a/web/cypress/fixtures/route-json-data.json +++ b/web/cypress/fixtures/route-json-data.json @@ -14,11 +14,13 @@ "vars": [], "upstream": { "type": "roundrobin", - "nodes": [{ - "host": "httpbin.org", - "port": 80, - "weight": 1 - }], + "nodes": [ + { + "host": "httpbin.org", + "port": 80, + "weight": 1 + } + ], "pass_host": "pass", "timeout": { "connect": 6, diff --git a/web/cypress/integration/consumer/create-consumer-with-api-breaker-plugin-form.spec.js b/web/cypress/integration/consumer/create-consumer-with-api-breaker-plugin-form.spec.js index a4df5d2caf..a5f2c09542 100644 --- a/web/cypress/integration/consumer/create-consumer-with-api-breaker-plugin-form.spec.js +++ b/web/cypress/integration/consumer/create-consumer-with-api-breaker-plugin-form.spec.js @@ -17,26 +17,25 @@ /* eslint-disable no-undef */ context('Create and delete consumer with api-breaker plugin form', () => { - const selector = { - break_response_code: "#break_response_code", - empty:'.ant-empty-normal', + break_response_code: '#break_response_code', + empty: '.ant-empty-normal', username: '#username', description: '#desc', pluginCard: '.ant-card', drawer: '.ant-drawer-content', disabledSwitcher: '#disable', notification: '.ant-notification-notice-message', - monacoViewZones: '.view-zones' - } + monacoViewZones: '.view-zones', + }; const data = { break_response_code: 200, consumerName: 'test_consumer', description: 'desc_by_autotest', createConsumerSuccess: 'Create Consumer Successfully', - deleteConsumerSuccess: 'Delete Consumer Successfully' - } + deleteConsumerSuccess: 'Delete Consumer Successfully', + }; beforeEach(() => { cy.login(); diff --git a/web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js b/web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js index 562b79c4a5..a676588114 100644 --- a/web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js +++ b/web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js @@ -17,9 +17,8 @@ /* eslint-disable no-undef */ context('Create and delete consumer with limit-count plugin form', () => { - const selector = { - empty:'.ant-empty-normal', + empty: '.ant-empty-normal', username: '#username', description: '#desc', pluginCard: '.ant-card', @@ -39,8 +38,8 @@ context('Create and delete consumer with limit-count plugin form', () => { redis_cluster_name: '#redis_cluster_name', redis_cluster_nodes_0: '#redis_cluster_nodes_0', redis_cluster_nodes_1: '#redis_cluster_nodes_1', - monacoViewZones: '.view-zones' - } + monacoViewZones: '.view-zones', + }; const data = { consumerName: 'test_consumer', @@ -49,7 +48,7 @@ context('Create and delete consumer with limit-count plugin form', () => { deleteConsumerSuccess: 'Delete Consumer Successfully', redisClusterName: 'Please Enter redis_cluster_name', redisClusterNode: 'Please Enter redis_cluster_node', - } + }; beforeEach(() => { cy.login(); @@ -122,7 +121,6 @@ context('Create and delete consumer with limit-count plugin form', () => { }); cy.get(selector.drawer).should('not.exist'); - // config limit-count form with redis-cluster policy cy.contains(selector.pluginCard, 'limit-count').within(() => { cy.contains('Enable').click({ diff --git a/web/cypress/integration/consumer/create-consumer-with-proxy-mirror-form.spec.js b/web/cypress/integration/consumer/create-consumer-with-proxy-mirror-form.spec.js index f49f35c871..700204c1ae 100644 --- a/web/cypress/integration/consumer/create-consumer-with-proxy-mirror-form.spec.js +++ b/web/cypress/integration/consumer/create-consumer-with-proxy-mirror-form.spec.js @@ -17,9 +17,8 @@ /* eslint-disable no-undef */ context('Create and delete consumer with proxy-mirror plugin form', () => { - const selector = { - empty:'.ant-empty-normal', + empty: '.ant-empty-normal', username: '#username', description: '#desc', pluginCard: '.ant-card', @@ -32,8 +31,8 @@ context('Create and delete consumer with proxy-mirror plugin form', () => { allow_origins_by_regex: '#allow_origins_by_regex_0', host: '#host', alert: '[role=alert]', - monacoViewZones: '.view-zones' - } + monacoViewZones: '.view-zones', + }; const data = { consumerName: 'test_consumer', @@ -41,7 +40,7 @@ context('Create and delete consumer with proxy-mirror plugin form', () => { createConsumerSuccess: 'Create Consumer Successfully', deleteConsumerSuccess: 'Delete Consumer Successfully', time: 2, - } + }; beforeEach(() => { cy.login(); diff --git a/web/cypress/integration/consumer/create-upstream-with-cors-form.spec.js b/web/cypress/integration/consumer/create-upstream-with-cors-form.spec.js index 03cb35ccbe..6dc7d5fc7f 100644 --- a/web/cypress/integration/consumer/create-upstream-with-cors-form.spec.js +++ b/web/cypress/integration/consumer/create-upstream-with-cors-form.spec.js @@ -17,9 +17,8 @@ /* eslint-disable no-undef */ context('Create and Delete Consumer', () => { - const selector = { - empty:'.ant-empty-normal', + empty: '.ant-empty-normal', username: '#username', description: '#desc', pluginCard: '.ant-card', @@ -34,8 +33,8 @@ context('Create and Delete Consumer', () => { remote_addr: '[title=remote_addr]', max_age: '#max_age', allow_origins_by_regex: '#allow_origins_by_regex_0', - monacoViewZones: '.view-zones' - } + monacoViewZones: '.view-zones', + }; const data = { consumerName: 'test_consumer', @@ -43,7 +42,7 @@ context('Create and Delete Consumer', () => { createConsumerSuccess: 'Create Consumer Successfully', deleteConsumerSuccess: 'Delete Consumer Successfully', time: 2, - } + }; beforeEach(() => { cy.login(); @@ -62,7 +61,7 @@ context('Create and Delete Consumer', () => { // config auth plugin cy.contains(selector.pluginCard, 'key-auth').within(() => { cy.contains('Enable').click({ - force: true + force: true, }); }); cy.focused(selector.drawer).should('exist'); diff --git a/web/cypress/integration/consumer/create-upstream-with-limit-req-form.spec.js b/web/cypress/integration/consumer/create-upstream-with-limit-req-form.spec.js index 1c4fa7ff6b..ccf144a92f 100644 --- a/web/cypress/integration/consumer/create-upstream-with-limit-req-form.spec.js +++ b/web/cypress/integration/consumer/create-upstream-with-limit-req-form.spec.js @@ -17,9 +17,8 @@ /* eslint-disable no-undef */ context('Create and Delete Consumer', () => { - const selector = { - empty:'.ant-empty-normal', + empty: '.ant-empty-normal', username: '#username', description: '#desc', pluginCard: '.ant-card', @@ -31,8 +30,8 @@ context('Create and Delete Consumer', () => { burst: '#burst', key: '#key', remote_addr: '[title=remote_addr]', - monacoViewZones: '.view-zones' - } + monacoViewZones: '.view-zones', + }; const data = { consumerName: 'test_consumer', @@ -40,7 +39,7 @@ context('Create and Delete Consumer', () => { createConsumerSuccess: 'Create Consumer Successfully', deleteConsumerSuccess: 'Delete Consumer Successfully', time: 2, - } + }; beforeEach(() => { cy.login(); diff --git a/web/cypress/integration/consumer/create-with-limit-conn-form.spec.js b/web/cypress/integration/consumer/create-with-limit-conn-form.spec.js index 4d096f3d42..b4cac1d5a6 100644 --- a/web/cypress/integration/consumer/create-with-limit-conn-form.spec.js +++ b/web/cypress/integration/consumer/create-with-limit-conn-form.spec.js @@ -17,9 +17,8 @@ /* eslint-disable no-undef */ context('Create and delete consumer with limit-conn plugin form', () => { - const selector = { - empty:'.ant-empty-normal', + empty: '.ant-empty-normal', username: '#username', description: '#desc', pluginCard: '.ant-card', @@ -34,8 +33,8 @@ context('Create and delete consumer with limit-conn plugin form', () => { key: '#key', rejected_code: '#rejected_code', title: '[title="remote_addr"]', - monacoViewZones: '.view-zones' - } + monacoViewZones: '.view-zones', + }; const data = { consumerName: 'test_consumer', @@ -46,7 +45,7 @@ context('Create and delete consumer with limit-conn plugin form', () => { burst: 0, default_conn_delay: 1, key: 'remote_addr', - } + }; beforeEach(() => { cy.login(); diff --git a/web/cypress/integration/consumer/create-with-referer-restriction-form.spec.js b/web/cypress/integration/consumer/create-with-referer-restriction-form.spec.js index eb9d7c2936..7d10f751aa 100644 --- a/web/cypress/integration/consumer/create-with-referer-restriction-form.spec.js +++ b/web/cypress/integration/consumer/create-with-referer-restriction-form.spec.js @@ -17,9 +17,8 @@ /* eslint-disable no-undef */ context('Create and delete Consumer with referer-restriction form ', () => { - const selector = { - empty:'.ant-empty-normal', + empty: '.ant-empty-normal', username: '#username', description: '#desc', pluginCard: '.ant-card', @@ -27,10 +26,10 @@ context('Create and delete Consumer with referer-restriction form ', () => { dropdown: '.rc-virtual-list', disabledSwitcher: '#disable', notification: '.ant-notification-notice-message', - whitelist: "#whitelist_0", - bypass_missing: "#bypass_missing", - monacoViewZones: '.view-zones' - } + whitelist: '#whitelist_0', + bypass_missing: '#bypass_missing', + monacoViewZones: '.view-zones', + }; const data = { consumerName: 'test_consumer', @@ -38,7 +37,7 @@ context('Create and delete Consumer with referer-restriction form ', () => { createConsumerSuccess: 'Create Consumer Successfully', deleteConsumerSuccess: 'Delete Consumer Successfully', whitelist: 'yy.com', - } + }; beforeEach(() => { cy.login(); diff --git a/web/cypress/integration/consumer/create_and_delete_consumer.spec.js b/web/cypress/integration/consumer/create_and_delete_consumer.spec.js index ffd669d88a..b510e20579 100644 --- a/web/cypress/integration/consumer/create_and_delete_consumer.spec.js +++ b/web/cypress/integration/consumer/create_and_delete_consumer.spec.js @@ -17,9 +17,8 @@ /* eslint-disable no-undef */ context('Create and Delete Consumer', () => { - const selector = { - empty:'.ant-empty-normal', + empty: '.ant-empty-normal', username: '#username', description: '#desc', pluginCard: '.ant-card', @@ -28,17 +27,17 @@ context('Create and Delete Consumer', () => { notification: '.ant-notification-notice-message', nameSelector: '[title=Name]', serviceSelector: '[title=test_service]', - monacoScroll: ".monaco-scrollable-element", - monacoViewZones: '.view-zones' - } + monacoScroll: '.monaco-scrollable-element', + monacoViewZones: '.view-zones', + }; const data = { consumerName: 'test_consumer', description: 'desc_by_autotest', createConsumerSuccess: 'Create Consumer Successfully', deleteConsumerSuccess: 'Delete Consumer Successfully', - pluginErrorAlert: 'Invalid plugin data' - } + pluginErrorAlert: 'Invalid plugin data', + }; beforeEach(() => { cy.login(); diff --git a/web/cypress/integration/dashboard/dashboard-smoketest.spec.js b/web/cypress/integration/dashboard/dashboard-smoketest.spec.js index 4a67c690c5..c2530f9065 100644 --- a/web/cypress/integration/dashboard/dashboard-smoketest.spec.js +++ b/web/cypress/integration/dashboard/dashboard-smoketest.spec.js @@ -19,7 +19,7 @@ context('dashboard page smoke test', () => { const selector = { pageContent: '.ant-pro-page-container', - } + }; beforeEach(() => { cy.login(); }); diff --git a/web/cypress/integration/lang/switch-language.spec.js b/web/cypress/integration/lang/switch-language.spec.js index dfdaf9a80f..bb86ba5937 100644 --- a/web/cypress/integration/lang/switch-language.spec.js +++ b/web/cypress/integration/lang/switch-language.spec.js @@ -21,7 +21,7 @@ context('Switch language', () => { const selector = { languageSwitcher: '.ant-space-align-center', - } + }; beforeEach(() => { cy.login(); diff --git a/web/cypress/integration/plugin/create-delete-in-drawer-plugin.spec.js b/web/cypress/integration/plugin/create-delete-in-drawer-plugin.spec.js index 0141c3b040..7aa9b3c996 100644 --- a/web/cypress/integration/plugin/create-delete-in-drawer-plugin.spec.js +++ b/web/cypress/integration/plugin/create-delete-in-drawer-plugin.spec.js @@ -30,11 +30,11 @@ context('Delete Plugin List with the Drawer', () => { checkedSwitcher: '.ant-switch-checked', refresh: '.anticon-reload', empty: '.ant-empty-normal', - } + }; const data = { basicAuthPlugin: 'basic-auth', - } + }; beforeEach(() => { cy.login(); @@ -45,28 +45,34 @@ context('Delete Plugin List with the Drawer', () => { cy.contains('Plugin').click(); cy.contains('Enable').click(); - cy.contains(data.basicAuthPlugin).parents(selector.pluginCardBordered).within(() => { - cy.get('button').click({ - force: true + cy.contains(data.basicAuthPlugin) + .parents(selector.pluginCardBordered) + .within(() => { + cy.get('button').click({ + force: true, + }); }); - }); - cy.get(selector.monacoMode).invoke('text').then(text => { - if (text === 'Form') { - cy.get(selector.monacoMode).click(); - cy.get(selector.selectDropdown).should('be.visible'); - cy.get(selector.selectJSON).click(); - } - }); + cy.get(selector.monacoMode) + .invoke('text') + .then((text) => { + if (text === 'Form') { + cy.get(selector.monacoMode).click(); + cy.get(selector.selectDropdown).should('be.visible'); + cy.get(selector.selectJSON).click(); + } + }); - cy.get(selector.drawer).should('be.visible').within(() => { - cy.get(selector.disabledSwitcher).click(); - cy.get(selector.checkedSwitcher).should('exist'); - }); + cy.get(selector.drawer) + .should('be.visible') + .within(() => { + cy.get(selector.disabledSwitcher).click(); + cy.get(selector.checkedSwitcher).should('exist'); + }); cy.contains('button', 'Submit').click(); cy.get(selector.drawer, { - timeout + timeout, }).should('not.exist'); }); @@ -75,27 +81,31 @@ context('Delete Plugin List with the Drawer', () => { cy.contains('Plugin').click(); cy.contains('Enable').click(); ['openid-connect', 'authz-keycloak'].forEach((plugin) => { - cy.contains(plugin).parents(selector.pluginCardBordered).within(() => { - cy.get('button').click({ - force: true + cy.contains(plugin) + .parents(selector.pluginCardBordered) + .within(() => { + cy.get('button').click({ + force: true, + }); }); - }); - cy.get(selector.drawer).should('be.visible').within(() => { - cy.contains('.ant-alert-warning', 'Doesn\'t need configuration').should('not.exist'); - cy.contains('button', 'Cancel').click(); - }); - }) - }) + cy.get(selector.drawer) + .should('be.visible') + .within(() => { + cy.contains('.ant-alert-warning', "Doesn't need configuration").should('not.exist'); + cy.contains('button', 'Cancel').click(); + }); + }); + }); it('should delete the plugin with the drawer', function () { cy.visit('/plugin/list'); cy.get(selector.refresh).click(); cy.contains('button', 'Configure').click(); cy.get(selector.drawerFooter).contains('button', 'Delete').click({ - force: true + force: true, }); cy.contains('button', 'Confirm').click({ - force: true + force: true, }); cy.get(selector.empty).should('be.visible'); }); diff --git a/web/cypress/integration/plugin/create-edit-delete-plugin.spec.js b/web/cypress/integration/plugin/create-edit-delete-plugin.spec.js index c924d29fcf..6f5f4335f0 100644 --- a/web/cypress/integration/plugin/create-edit-delete-plugin.spec.js +++ b/web/cypress/integration/plugin/create-edit-delete-plugin.spec.js @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* eslint-disable no-undef */ +/* eslint-disable */ context('Enable and Delete Plugin List', () => { const timeout = 5000; @@ -55,12 +55,14 @@ context('Enable and Delete Plugin List', () => { cy.get(this.domSelector.fiftyPerPage).should('exist'); cy.location('href').should('include', 'pageSize=50'); - cy.get(this.domSelector.deleteButton, { timeout }).should('exist').each(function ($el) { - cy.wrap($el).click().click({ timeout }); - cy.contains('button', 'Confirm').click({ force: true }); - cy.get(this.domSelector.notification).should('contain', this.data.deletePluginSuccess); - cy.get(this.domSelector.notificationCloseIcon).click().should('not.exist'); - }); + cy.get(this.domSelector.deleteButton, { timeout }) + .should('exist') + .each(function ($el) { + cy.wrap($el).click().click({ timeout }); + cy.contains('button', 'Confirm').click({ force: true }); + cy.get(this.domSelector.notification).should('contain', this.data.deletePluginSuccess); + cy.get(this.domSelector.notificationCloseIcon).click().should('not.exist'); + }); // check if plugin list is empty cy.get(this.domSelector.empty).should('be.visible'); diff --git a/web/cypress/integration/pluginTemplate/create-edit-delete-plugin-template.spec.js b/web/cypress/integration/pluginTemplate/create-edit-delete-plugin-template.spec.js index 2567931c09..706135b799 100644 --- a/web/cypress/integration/pluginTemplate/create-edit-delete-plugin-template.spec.js +++ b/web/cypress/integration/pluginTemplate/create-edit-delete-plugin-template.spec.js @@ -17,7 +17,6 @@ /* eslint-disable no-undef */ context('Create Configure and Delete PluginTemplate', () => { - const selector = { pluginCard: '.ant-card', empty: '.ant-empty-normal', diff --git a/web/cypress/integration/rawDataEditor/test-rawDataEditor.spec.js b/web/cypress/integration/rawDataEditor/test-rawDataEditor.spec.js index f89b341f21..797536381c 100644 --- a/web/cypress/integration/rawDataEditor/test-rawDataEditor.spec.js +++ b/web/cypress/integration/rawDataEditor/test-rawDataEditor.spec.js @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* eslint-disable no-undef */ +/* eslint-disable */ context('Test RawDataEditor', () => { const timeout = 1000; @@ -24,7 +24,7 @@ context('Test RawDataEditor', () => { tableBody: '.ant-table-tbody', drawer: '.ant-drawer-content', notification: '.ant-notification-notice-message', - monacoViewZones: '.view-zones' + monacoViewZones: '.view-zones', }; const data = { diff --git a/web/cypress/integration/route/check-route-required-field-flag.spec.js b/web/cypress/integration/route/check-route-required-field-flag.spec.js index 13e2a64412..bdf7345ab2 100644 --- a/web/cypress/integration/route/check-route-required-field-flag.spec.js +++ b/web/cypress/integration/route/check-route-required-field-flag.spec.js @@ -25,29 +25,27 @@ context('Check Route Required Field Flag', () => { cy.visit('/'); cy.contains('Route').click(); cy.contains('Create').click(); - cy.get('label[title="Name"]') - .then($els => { - // get Window reference from element - const win = $els[0].ownerDocument.defaultView - // use getComputedStyle to read the pseudo selector - const before = win.getComputedStyle($els[0], 'before') - // read the value of the `content` CSS property - const contentValue = before.getPropertyValue('content') - // the returned value will have double quotes around it, but this is correct - expect(contentValue).to.eq('"*"') - }) + cy.get('label[title="Name"]').then(($els) => { + // get Window reference from element + const win = $els[0].ownerDocument.defaultView; + // use getComputedStyle to read the pseudo selector + const before = win.getComputedStyle($els[0], 'before'); + // read the value of the `content` CSS property + const contentValue = before.getPropertyValue('content'); + // the returned value will have double quotes around it, but this is correct + expect(contentValue).to.eq('"*"'); + }); }); it('should exist required flag for Route path', function () { cy.visit('/'); cy.contains('Route').click(); cy.contains('Create').click(); - cy.get('label[title="Path"]') - .then($els => { - const win = $els[0].ownerDocument.defaultView - const before = win.getComputedStyle($els[0], 'before') - const contentValue = before.getPropertyValue('content') - expect(contentValue).to.eq('"*"') - }) + cy.get('label[title="Path"]').then(($els) => { + const win = $els[0].ownerDocument.defaultView; + const before = win.getComputedStyle($els[0], 'before'); + const contentValue = before.getPropertyValue('content'); + expect(contentValue).to.eq('"*"'); + }); }); }); diff --git a/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js b/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js index 87e3cbfcb8..952833cb7a 100644 --- a/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js +++ b/web/cypress/integration/route/create-edit-duplicate-delete-route.spec.js @@ -47,14 +47,14 @@ context('Create and Delete Route', () => { selectJSON: '.ant-select-dropdown [label=JSON]', drawerFooter: '.ant-drawer-footer', nameSelector: '[title=Name]', - monacoScroll: ".monaco-scrollable-element", + monacoScroll: '.monaco-scrollable-element', deleteAlert: '.ant-modal-body', notificationCloseIcon: '.ant-notification-close-icon', notification: '.ant-notification-notice-message', addHost: '[data-cy=addHost]', - schemaErrorMessage: ".ant-form-item-explain.ant-form-item-explain-error", - advancedMatchingTable: ".ant-table-row.ant-table-row-level-0", - advancedMatchingTableOperation: ".ant-space" + schemaErrorMessage: '.ant-form-item-explain.ant-form-item-explain-error', + advancedMatchingTable: '.ant-table-row.ant-table-row-level-0', + advancedMatchingTableOperation: '.ant-space', }; const data = { @@ -183,7 +183,7 @@ context('Create and Delete Route', () => { cy.get(selector.monacoScroll).within(() => { cy.contains('upstream').should('exist'); - cy.contains('vars').should('exist') + cy.contains('vars').should('exist'); cy.contains(name).should('exist'); }); }); diff --git a/web/cypress/integration/route/create-edit-route-with-redirect-plugin.spec.js b/web/cypress/integration/route/create-edit-route-with-redirect-plugin.spec.js index c6537055f3..15662dc5e9 100644 --- a/web/cypress/integration/route/create-edit-route-with-redirect-plugin.spec.js +++ b/web/cypress/integration/route/create-edit-route-with-redirect-plugin.spec.js @@ -27,7 +27,7 @@ context('Create Edit and Delete Route with redirect plugin', () => { customRedirectSelectOpt: '#redirectOption_list_1', customRedirectUrI: '#redirectURI', customRedirectCode: '[data-cy=redirect_code]', - customRedirectLabel: '[title=\'Custom Redirect\']', + customRedirectLabel: "[title='Custom Redirect']", deleteAlert: '.ant-modal-body', notificationCloseIcon: '.ant-notification-close-icon', notification: '.ant-notification-notice-message', @@ -39,7 +39,7 @@ context('Create Edit and Delete Route with redirect plugin', () => { deleteRouteSuccess: 'Delete Route Successfully', step2Title: 'Define API Backend Server', step3Title: 'Plugin Config', - setUpstreamNotice: 'If you do not bind the service, you must set the Upstream (Step 2)' + setUpstreamNotice: 'If you do not bind the service, you must set the Upstream (Step 2)', }; beforeEach(() => { @@ -54,7 +54,7 @@ context('Create Edit and Delete Route with redirect plugin', () => { cy.contains('Next').click().click(); cy.get(selector.name).type(name); cy.get(selector.redirect).click(); - cy.contains('Custom').click({force: true}); + cy.contains('Custom').click({ force: true }); // after choose Custom option, Custom Redirect form field should be visible cy.get(selector.customRedirectLabel).should('be.visible'); cy.get(selector.customRedirectUrI).should('be.visible'); @@ -94,7 +94,6 @@ context('Create Edit and Delete Route with redirect plugin', () => { cy.contains('Goto List').click(); cy.url().should('contains', 'routes/list'); cy.contains(newName).should('be.visible'); - }); it('should delete the route', function () { @@ -104,11 +103,11 @@ context('Create Edit and Delete Route with redirect plugin', () => { cy.contains(newName).siblings().contains('More').click(); cy.contains('Delete').click(); cy.get(selector.deleteAlert) - .should('be.visible') - .within(() => { + .should('be.visible') + .within(() => { cy.contains('OK').click(); - }); + }); cy.get(selector.notification).should('contain', data.deleteRouteSuccess); - cy.get(selector.notificationCloseIcon).click({multiple: true}); + cy.get(selector.notificationCloseIcon).click({ multiple: true }); }); }); diff --git a/web/cypress/integration/route/create-route-when-not-select-upsteam-id.spec.js b/web/cypress/integration/route/create-route-when-not-select-upsteam-id.spec.js index 6057011264..adda2568cd 100644 --- a/web/cypress/integration/route/create-route-when-not-select-upsteam-id.spec.js +++ b/web/cypress/integration/route/create-route-when-not-select-upsteam-id.spec.js @@ -17,7 +17,6 @@ /* eslint-disable no-undef */ context('Create Route without Upstream', () => { - const selector = { name: '#name', nodes_0_host: '#nodes_0_host', diff --git a/web/cypress/integration/route/create-route-with-chash-upstream.spec.js b/web/cypress/integration/route/create-route-with-chash-upstream.spec.js index f2aef94371..1a014bb20f 100644 --- a/web/cypress/integration/route/create-route-with-chash-upstream.spec.js +++ b/web/cypress/integration/route/create-route-with-chash-upstream.spec.js @@ -23,8 +23,8 @@ context('Create and Edit Route With Custom CHash Key Upstream', () => { roundRobinSelect: '[title="Round Robin"]', varSelect: '[title="vars"]', defaultCHashKey: '[value="remote_addr"]', - upstreamType: ".ant-select-item-option-content", - hashPosition: ".ant-select-item-option-content", + upstreamType: '.ant-select-item-option-content', + hashPosition: '.ant-select-item-option-content', nodes_0_host: '#nodes_0_host', nodes_0_port: '#nodes_0_port', nodes_0_weight: '#nodes_0_weight', @@ -119,6 +119,6 @@ context('Create and Edit Route With Custom CHash Key Upstream', () => { cy.contains('OK').click(); }); cy.get(selector.notification).should('contain', data.deleteRouteSuccess); - cy.get(selector.notificationCloseIcon).click({multiple: true}); + cy.get(selector.notificationCloseIcon).click({ multiple: true }); }); }); diff --git a/web/cypress/integration/route/create-route-with-cors-form.spec.js b/web/cypress/integration/route/create-route-with-cors-form.spec.js index 3c9471136f..67ee8f43bb 100644 --- a/web/cypress/integration/route/create-route-with-cors-form.spec.js +++ b/web/cypress/integration/route/create-route-with-cors-form.spec.js @@ -31,11 +31,11 @@ context('Create and delete route with cors form', () => { deleteAlert: '.ant-modal-body', notificationCloseIcon: '.ant-notification-close-icon', notification: '.ant-notification-notice-message', - allow_credential: "#allow_credential", - allow_origins_by_regex0: "#allow_origins_by_regex_0", - allow_origins_by_regex1: "#allow_origins_by_regex_1", - addButton: "[data-cy=add-allow_origins_by_regex]", - } + allow_credential: '#allow_credential', + allow_origins_by_regex0: '#allow_origins_by_regex_0', + allow_origins_by_regex1: '#allow_origins_by_regex_1', + addButton: '[data-cy=add-allow_origins_by_regex]', + }; const data = { deleteRouteSuccess: 'Delete Route Successfully', @@ -64,16 +64,20 @@ context('Create and delete route with cors form', () => { cy.contains('Next').click(); // config cors plugin - cy.contains('cors').parents(selector.pluginCardBordered).within(() => { - cy.get('button').click({ - force: true + cy.contains('cors') + .parents(selector.pluginCardBordered) + .within(() => { + cy.get('button').click({ + force: true, + }); }); - }); - cy.get(selector.drawer).should('be.visible').within(() => { - cy.get(selector.disabledSwitcher).click(); - cy.get(selector.checkedSwitcher).should('exist'); - }); + cy.get(selector.drawer) + .should('be.visible') + .within(() => { + cy.get(selector.disabledSwitcher).click(); + cy.get(selector.checkedSwitcher).should('exist'); + }); // config cors form cy.get(selector.allow_credential).click(); @@ -83,7 +87,10 @@ context('Create and delete route with cors form', () => { cy.get(selector.addButton).click(); cy.get(selector.allow_origins_by_regex1).should('exist'); cy.get(selector.allow_origins_by_regex0).next().should('have.class', 'anticon-minus-circle'); - cy.get(selector.allow_origins_by_regex1).type('foo.com').next().should('have.class', 'anticon-minus-circle'); + cy.get(selector.allow_origins_by_regex1) + .type('foo.com') + .next() + .should('have.class', 'anticon-minus-circle'); cy.get(selector.drawer).within(() => { cy.contains('Submit').click({ @@ -107,21 +114,25 @@ context('Create and delete route with cors form', () => { cy.get(selector.name).clear().type('routeName'); cy.contains('Search').click(); cy.contains('routeName').siblings().contains('Configure').click(); - cy.get(selector.name).should('have.value','routeName'); + cy.get(selector.name).should('have.value', 'routeName'); cy.contains('Next').click(); cy.contains('Next').click(); // config cors plugin - cy.contains('cors').parents(selector.pluginCardBordered).within(() => { - cy.get('button').click({ - force: true + cy.contains('cors') + .parents(selector.pluginCardBordered) + .within(() => { + cy.get('button').click({ + force: true, + }); }); - }); - cy.get(selector.drawer).should('be.visible').within(() => { - cy.get(selector.disabledSwitcher).click(); - cy.get(selector.checkedSwitcher).should('exist'); - }); + cy.get(selector.drawer) + .should('be.visible') + .within(() => { + cy.get(selector.disabledSwitcher).click(); + cy.get(selector.checkedSwitcher).should('exist'); + }); // edit allow_origins_by_regex '' cy.get(selector.allow_origins_by_regex0).clear(); @@ -149,10 +160,12 @@ context('Create and delete route with cors form', () => { cy.contains('Search').click(); 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.deleteAlert) + .should('be.visible') + .within(() => { + cy.contains('OK').click(); + }); cy.get(selector.notification).should('contain', data.deleteRouteSuccess); - cy.get(selector.notificationCloseIcon).click({ multiple: true}); + cy.get(selector.notificationCloseIcon).click({ multiple: true }); }); }); diff --git a/web/cypress/integration/route/create-route-with-limit-count-plugin-form.spec.js b/web/cypress/integration/route/create-route-with-limit-count-plugin-form.spec.js index 78c7734600..2ab7d0ff96 100644 --- a/web/cypress/integration/route/create-route-with-limit-count-plugin-form.spec.js +++ b/web/cypress/integration/route/create-route-with-limit-count-plugin-form.spec.js @@ -53,7 +53,7 @@ context('Create and delete route with limit-count form', () => { weight: 1, redisClusterName: 'Please Enter redis_cluster_name', redisClusterNode: 'Please Enter redis_cluster_node', - } + }; beforeEach(() => { cy.login(); diff --git a/web/cypress/integration/route/search-route.spec.js b/web/cypress/integration/route/search-route.spec.js index 2c8c601092..77b5def307 100644 --- a/web/cypress/integration/route/search-route.spec.js +++ b/web/cypress/integration/route/search-route.spec.js @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* eslint-disable no-undef */ +/* eslint-disable */ context('Create and Search Route', () => { const timeout = 500; @@ -39,7 +39,7 @@ context('Create and Search Route', () => { drawerBody: '.ant-drawer-wrapper-body', notification: '.ant-notification-notice-message', notificationClose: '.anticon-close', - expandSearch: '.ant-pro-form-collapse-button' + expandSearch: '.ant-pro-form-collapse-button', }; const data = { diff --git a/web/cypress/integration/service/create-edit-delete-service.spec.js b/web/cypress/integration/service/create-edit-delete-service.spec.js index 74ae8f8732..bb0ac4eafd 100644 --- a/web/cypress/integration/service/create-edit-delete-service.spec.js +++ b/web/cypress/integration/service/create-edit-delete-service.spec.js @@ -29,7 +29,7 @@ context('Create and Delete Service ', () => { disabledSwitcher: '#disable', drawer: '.ant-drawer-content', checkedSwitcher: '.ant-switch-checked', - monacoScroll: ".monaco-scrollable-element", + monacoScroll: '.monaco-scrollable-element', monacoMode: "[data-cy='monaco-mode']", selectDropdown: '.ant-select-dropdown', selectJSON: '.ant-select-dropdown [label=JSON]', diff --git a/web/cypress/integration/service/create-service-with-chash-upstream.spec.js b/web/cypress/integration/service/create-service-with-chash-upstream.spec.js index e61358616e..59daec6182 100644 --- a/web/cypress/integration/service/create-service-with-chash-upstream.spec.js +++ b/web/cypress/integration/service/create-service-with-chash-upstream.spec.js @@ -26,8 +26,8 @@ context('Create and Edit Service with Custom CHash Key Upstream', () => { nodes_0_host: '#nodes_0_host', nodes_0_port: '#nodes_0_port', nodes_0_weight: '#nodes_0_weight', - upstreamType: ".ant-select-item-option-content", - hashPosition: ".ant-select-item-option-content", + upstreamType: '.ant-select-item-option-content', + hashPosition: '.ant-select-item-option-content', chash_key: '#key', notification: '.ant-notification-notice-message', nameSearch: '[title=Name]', @@ -93,7 +93,6 @@ context('Create and Edit Service with Custom CHash Key Upstream', () => { cy.get(selector.notification).should('contain', data.editServiceSuccess); }); - it('should delete this service', function () { cy.visit('/service/list'); cy.get(selector.nameSearch).type(data.serviceName); diff --git a/web/cypress/integration/upstream/create_and_delete_upstream.spec.js b/web/cypress/integration/upstream/create_and_delete_upstream.spec.js index 7d8a48d9cf..31aba9f428 100644 --- a/web/cypress/integration/upstream/create_and_delete_upstream.spec.js +++ b/web/cypress/integration/upstream/create_and_delete_upstream.spec.js @@ -17,32 +17,31 @@ /* eslint-disable no-undef */ context('Create and Delete Upstream', () => { - const selector = { - "name": "#name", - "nodes_0_host": "#nodes_0_host", - "nodes_0_port": "#nodes_0_port", - "nodes_0_weight": "#nodes_0_weight", - "input": ":input", - "notification": ".ant-notification-notice-message", - "nameSelector": "[title=Name]", - "upstreamType": ".ant-select-item-option-content", - "drawer": ".ant-drawer-content", - "monacoScroll": ".monaco-scrollable-element", - "description": "#desc", - } + name: '#name', + nodes_0_host: '#nodes_0_host', + nodes_0_port: '#nodes_0_port', + nodes_0_weight: '#nodes_0_weight', + input: ':input', + notification: '.ant-notification-notice-message', + nameSelector: '[title=Name]', + upstreamType: '.ant-select-item-option-content', + drawer: '.ant-drawer-content', + monacoScroll: '.monaco-scrollable-element', + description: '#desc', + }; const data = { - "upstreamName": "test_upstream", - "description": "desc_by_autotest", - "ip1": "127.0.0.1", - "createUpstreamSuccess": "Create Upstream Successfully", - "deleteUpstreamSuccess": "Delete Upstream Successfully", - "port0": "7000", - "weight0": "2", - "port1": "7001", - "weight1": "2" - } + upstreamName: 'test_upstream', + description: 'desc_by_autotest', + ip1: '127.0.0.1', + createUpstreamSuccess: 'Create Upstream Successfully', + deleteUpstreamSuccess: 'Delete Upstream Successfully', + port0: '7000', + weight0: '2', + port1: '7001', + weight1: '2', + }; beforeEach(() => { cy.login(); @@ -77,7 +76,7 @@ context('Create and Delete Upstream', () => { cy.get('.ant-drawer-content').should('be.visible'); cy.get(selector.monacoScroll).within(() => { - cy.contains('nodes').should("exist"); + cy.contains('nodes').should('exist'); cy.contains('roundrobin').should('exist'); cy.contains(data.upstreamName).should('exist'); }); @@ -141,7 +140,7 @@ context('Create and Delete Upstream', () => { cy.get(selector.drawer).should('be.visible'); cy.get(selector.monacoScroll).within(() => { - cy.contains('nodes').should("exist"); + cy.contains('nodes').should('exist'); cy.contains('chash').should('exist'); cy.contains(data.upstreamName).should('exist'); }); diff --git a/web/cypress/integration/upstream/create_and_edit_upstream_with_custom_chash_key.spec.js b/web/cypress/integration/upstream/create_and_edit_upstream_with_custom_chash_key.spec.js index dda114593f..0b3b9236f6 100644 --- a/web/cypress/integration/upstream/create_and_edit_upstream_with_custom_chash_key.spec.js +++ b/web/cypress/integration/upstream/create_and_edit_upstream_with_custom_chash_key.spec.js @@ -26,8 +26,8 @@ context('Create and Delete Upstream With Custom CHash Key', () => { nodes_0_host: '#nodes_0_host', nodes_0_port: '#nodes_0_port', nodes_0_weight: '#nodes_0_weight', - upstreamType: ".ant-select-item-option-content", - hashPosition: ".ant-select-item-option-content", + upstreamType: '.ant-select-item-option-content', + hashPosition: '.ant-select-item-option-content', chash_key: '#key', notification: '.ant-notification-notice-message', nameSelector: '[title=Name]', diff --git a/web/cypress/support/commands.js b/web/cypress/support/commands.js index e46ca78372..72d18b343e 100644 --- a/web/cypress/support/commands.js +++ b/web/cypress/support/commands.js @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* eslint-disable no-undef */ +/* eslint-disable */ import defaultSettings from '../../config/defaultSettings'; import 'cypress-file-upload'; import '@4tw/cypress-drag-drop'; @@ -45,7 +45,7 @@ Cypress.Commands.add('configurePlugins', (cases) => { selectDropdown: '.ant-select-dropdown', monacoMode: '[data-cy="monaco-mode"]', selectJSON: '.ant-select-dropdown [label=JSON]', - monacoViewZones: '.view-zones' + monacoViewZones: '.view-zones', }; cy.get(domSelector.name, { timeout }).then(function (cards) { @@ -69,15 +69,17 @@ Cypress.Commands.add('configurePlugins', (cases) => { // NOTE: wait for the Drawer to appear on the DOM cy.focused(domSelector.drawer).should('exist'); - cy.get(domSelector.monacoMode).invoke('text').then(text => { - if (text === 'Form') { - cy.wait(5000); - cy.get(domSelector.monacoMode).should('be.visible'); - cy.get(domSelector.monacoMode).click(); - cy.get(domSelector.selectDropdown).should('be.visible'); - cy.get(domSelector.selectJSON).click(); - } - }); + cy.get(domSelector.monacoMode) + .invoke('text') + .then((text) => { + if (text === 'Form') { + cy.wait(5000); + cy.get(domSelector.monacoMode).should('be.visible'); + cy.get(domSelector.monacoMode).click(); + cy.get(domSelector.selectDropdown).should('be.visible'); + cy.get(domSelector.selectJSON).click(); + } + }); cy.get(domSelector.drawer, { timeout }).within(() => { cy.get(domSelector.switch).click({ @@ -85,16 +87,18 @@ Cypress.Commands.add('configurePlugins', (cases) => { }); }); - cy.get(domSelector.monacoMode).invoke('text').then(text => { - if (text === 'Form') { - // FIXME: https://github.com/cypress-io/cypress/issues/7306 - cy.wait(5000); - cy.get(domSelector.monacoMode).should('be.visible'); - cy.get(domSelector.monacoMode).click(); - cy.get(domSelector.selectDropdown).should('be.visible'); - cy.get(domSelector.selectJSON).click(); - } - }); + cy.get(domSelector.monacoMode) + .invoke('text') + .then((text) => { + if (text === 'Form') { + // FIXME: https://github.com/cypress-io/cypress/issues/7306 + cy.wait(5000); + cy.get(domSelector.monacoMode).should('be.visible'); + cy.get(domSelector.monacoMode).click(); + cy.get(domSelector.selectDropdown).should('be.visible'); + cy.get(domSelector.selectJSON).click(); + } + }); // edit monaco cy.get(domSelector.monacoViewZones).should('exist').click({ force: true }); cy.window().then((window) => { diff --git a/web/src/components/LabelsfDrawer/LabelsDrawer.tsx b/web/src/components/LabelsfDrawer/LabelsDrawer.tsx index 9f6ff5b38c..467a597703 100644 --- a/web/src/components/LabelsfDrawer/LabelsDrawer.tsx +++ b/web/src/components/LabelsfDrawer/LabelsDrawer.tsx @@ -25,8 +25,8 @@ type Props = { title?: string; actionName: string; dataSource: string[]; - filterList?: string[], - fetchLabelList: any, + filterList?: string[]; + fetchLabelList: any; disabled: boolean; onClose: () => void; } & Pick; @@ -113,14 +113,14 @@ const LabelList = (disabled: boolean, labelList: LabelList, filterList: string[] }; const LabelsDrawer: React.FC = ({ - title = "", + title = '', actionName = '', disabled = false, dataSource = [], filterList = [], fetchLabelList, onClose, - onChange = () => { }, + onChange = () => {}, }) => { const transformLabel = transformLableValueToKeyValue(dataSource); @@ -135,7 +135,7 @@ const LabelsDrawer: React.FC = ({ return ( {title}   - {tooltip && } + {tooltip && ( + + + + )}
{children}
diff --git a/web/src/components/Plugin/PluginDetail.tsx b/web/src/components/Plugin/PluginDetail.tsx index 882a910c7a..6137299b64 100644 --- a/web/src/components/Plugin/PluginDetail.tsx +++ b/web/src/components/Plugin/PluginDetail.tsx @@ -36,9 +36,9 @@ import Ajv from 'ajv'; import type { DefinedError } from 'ajv'; import addFormats from 'ajv-formats'; import { compact, omit } from 'lodash'; -import type { Monaco } from "@monaco-editor/react"; -import Editor from "@monaco-editor/react"; -import type {languages} from "monaco-editor"; +import type { Monaco } from '@monaco-editor/react'; +import Editor from '@monaco-editor/react'; +import type { languages } from 'monaco-editor'; import { fetchSchema } from './service'; import { json2yaml, yaml2json } from '../../helpers'; @@ -94,14 +94,14 @@ const PluginDetail: React.FC = ({ maskClosable = true, isEnabled = false, initialData = {}, - onClose = () => { }, - onChange = () => { }, + onClose = () => {}, + onChange = () => {}, }) => { const { formatMessage } = useIntl(); enum monacoModeList { JSON = 'JSON', YAML = 'YAML', - UIForm = 'Form' + UIForm = 'Form', } const [form] = Form.useForm(); const [UIForm] = Form.useForm(); @@ -116,17 +116,20 @@ const PluginDetail: React.FC = ({ ]; if (PLUGIN_UI_LIST.includes(name)) { - modeOptions.push({ label: formatMessage({ id: 'component.plugin.form' }), value: monacoModeList.UIForm }); + modeOptions.push({ + label: formatMessage({ id: 'component.plugin.form' }), + value: monacoModeList.UIForm, + }); } const getUIFormData = () => { if (name === 'cors') { const formData = UIForm.getFieldsValue(); - const newMethods = formData.allow_methods.join(","); + const newMethods = formData.allow_methods.join(','); const compactAllowRegex = compact(formData.allow_origins_by_regex); // Note: default allow_origins_by_regex setted for UI is [''], but this is not allowed, omit it. if (compactAllowRegex.length === 0) { - return omit({ ...formData, allow_methods: newMethods }, ['allow_origins_by_regex']) + return omit({ ...formData, allow_methods: newMethods }, ['allow_origins_by_regex']); } return { ...formData, allow_methods: newMethods }; @@ -136,7 +139,9 @@ const PluginDetail: React.FC = ({ const setUIFormData = (formData: any) => { if (name === 'cors' && formData) { - const methods = (formData.allow_methods || '').length ? formData.allow_methods.split(",") : ["*"]; + const methods = (formData.allow_methods || '').length + ? formData.allow_methods.split(',') + : ['*']; UIForm.setFieldsValue({ ...formData, allow_methods: methods }); return; } @@ -145,7 +150,7 @@ const PluginDetail: React.FC = ({ useEffect(() => { form.setFieldsValue({ - disable: isEnabled ? true : (initialData[name] && !initialData[name].disable), + disable: isEnabled ? true : initialData[name] && !initialData[name].disable, scope: 'global', }); if (PLUGIN_UI_LIST.includes(name)) { @@ -155,15 +160,15 @@ const PluginDetail: React.FC = ({ }, []); const formatYaml = (yaml: string): string => { - const json=yaml2json(yaml,true) - if (json.error){ - return yaml + const json = yaml2json(yaml, true); + if (json.error) { + return yaml; } return json2yaml(json.data).data; - } + }; const editorWillMount = (monaco: Monaco) => { - fetchSchema(name, schemaType).then((schema)=> { + fetchSchema(name, schemaType).then((schema) => { const schemaConfig: languages.json.DiagnosticsOptions = { validate: true, schemas: [ @@ -171,25 +176,27 @@ const PluginDetail: React.FC = ({ // useless placeholder uri: `https://apisix.apache.org/`, fileMatch: ['*'], - schema - } + schema, + }, ], - trailingCommas: "error", - enableSchemaRequest: false + trailingCommas: 'error', + enableSchemaRequest: false, }; const yamlFormatProvider: languages.DocumentFormattingEditProvider = { provideDocumentFormattingEdits(model) { - return [{ - text: formatYaml(model.getValue()), - range: model.getFullModelRange() - }]; - } + return [ + { + text: formatYaml(model.getValue()), + range: model.getFullModelRange(), + }, + ]; + }, }; - monaco.languages.registerDocumentFormattingEditProvider("yaml",yamlFormatProvider); - monaco.editor.getModels().forEach(model => model.updateOptions({tabSize: 2})); + monaco.languages.registerDocumentFormattingEditProvider('yaml', yamlFormatProvider); + monaco.editor.getModels().forEach((model) => model.updateOptions({ tabSize: 2 })); monaco.languages.json.jsonDefaults.setDiagnosticsOptions(schemaConfig); - }) - } + }); + }; const validateData = (pluginName: string, value: PluginComponent.Data) => { return fetchSchema(pluginName, schemaType).then((schema) => { @@ -242,20 +249,21 @@ const PluginDetail: React.FC = ({ if (monacoMode === monacoModeList.YAML) { const { data: yamlData, error } = yaml2json(content, true); if (error) { - notification.error({message: formatMessage({id: 'component.global.invalidYaml'})}); + notification.error({ message: formatMessage({ id: 'component.global.invalidYaml' }) }); return; } - setContent(js_beautify(yamlData, { indent_size: 2 })) + setContent(js_beautify(yamlData, { indent_size: 2 })); } else { - setContent(js_beautify(JSON.stringify(getUIFormData()), { indent_size: 2 })) + setContent(js_beautify(JSON.stringify(getUIFormData()), { indent_size: 2 })); } break; } case monacoModeList.YAML: { - const jsonData = monacoMode === monacoModeList.JSON ? content : JSON.stringify(getUIFormData()); + const jsonData = + monacoMode === monacoModeList.JSON ? content : JSON.stringify(getUIFormData()); const { data: yamlData, error } = json2yaml(jsonData); - if (error){ - notification.error({ message: formatMessage({ id:'component.global.invalidJson' }) }); + if (error) { + notification.error({ message: formatMessage({ id: 'component.global.invalidJson' }) }); return; } setContent(yamlData); @@ -268,7 +276,7 @@ const PluginDetail: React.FC = ({ } else { const { data: yamlData, error } = yaml2json(content, true); if (error) { - notification.error({ message: formatMessage({ id:'component.global.invalidYaml' }) }); + notification.error({ message: formatMessage({ id: 'component.global.invalidYaml' }) }); return; } setUIFormData(JSON.parse(yamlData)); @@ -281,7 +289,8 @@ const PluginDetail: React.FC = ({ setMonacoMode(value); }; - const isNoConfigurationRequired = pluginType === 'auth' && schemaType !== 'consumer' && (monacoMode !== monacoModeList.UIForm); + const isNoConfigurationRequired = + pluginType === 'auth' && schemaType !== 'consumer' && monacoMode !== monacoModeList.UIForm; return ( = ({ onChange({ formData: form.getFieldsValue(), monacoData: value }); }); } catch (error) { - notification.error({ message: formatMessage({ id:'component.global.invalidJson' }) }); + notification.error({ + message: formatMessage({ id: 'component.global.invalidJson' }), + }); } }} > @@ -364,7 +375,11 @@ const PluginDetail: React.FC = ({ - + = ({ {type === 'global' && ( )} @@ -383,7 +398,10 @@ const PluginDetail: React.FC = ({ title="" subTitle={ isNoConfigurationRequired ? ( - + ) : null } ghost={false} @@ -393,7 +411,7 @@ const PluginDetail: React.FC = ({ value={monacoMode} options={modeOptions} onChange={handleModeChange} - data-cy='monaco-mode' + data-cy="monaco-mode" key={1} />, + , ]} /> - {Boolean(monacoMode === monacoModeList.UIForm) && } + {Boolean(monacoMode === monacoModeList.UIForm) && ( + + )}
{ + onChange={(text) => { if (text) { setContent(text); } else { @@ -424,7 +449,7 @@ const PluginDetail: React.FC = ({ } }} language={monacoMode.toLocaleLowerCase()} - onMount={(editor)=>{ + onMount={(editor) => { // NOTE: for debug & test // @ts-ignore window.monacoEditor = editor; @@ -435,8 +460,8 @@ const PluginDetail: React.FC = ({ vertical: 'hidden', horizontal: 'hidden', }, - wordWrap: "on", - minimap: {enabled: false}, + wordWrap: 'on', + minimap: { enabled: false }, readOnly: readonly, }} /> diff --git a/web/src/components/Plugin/PluginPage.tsx b/web/src/components/Plugin/PluginPage.tsx index 609ddc313e..3f5a52e79c 100644 --- a/web/src/components/Plugin/PluginPage.tsx +++ b/web/src/components/Plugin/PluginPage.tsx @@ -28,11 +28,11 @@ import defaultPluginImg from '../../../public/static/default-plugin.png'; type Props = { readonly?: boolean; type?: 'global' | 'scoped'; - initialData?: PluginComponent.Data, - plugin_config_id?: string, + initialData?: PluginComponent.Data; + plugin_config_id?: string; schemaType?: PluginComponent.Schema; referPage?: PluginComponent.ReferPage; - showSelector?: boolean, + showSelector?: boolean; onChange?: (plugins: PluginComponent.Data, plugin_config_id?: string) => void; }; @@ -52,17 +52,19 @@ const NEVER_EXIST_PLUGIN_FLAG = 'NEVER_EXIST_PLUGIN_FLAG'; const PluginPage: React.FC = ({ readonly = false, initialData = {}, - plugin_config_id = "", + plugin_config_id = '', schemaType = 'route', referPage = '', type = 'scoped', showSelector = false, - onChange = () => { }, + onChange = () => {}, }) => { const { formatMessage } = useIntl(); const [form] = Form.useForm(); const [pluginList, setPluginList] = useState([]); - const [pluginTemplateList, setPluginTemplateList] = useState([]); + const [pluginTemplateList, setPluginTemplateList] = useState( + [], + ); const [name, setName] = useState(NEVER_EXIST_PLUGIN_FLAG); const [typeList, setTypeList] = useState([]); const [plugins, setPlugins] = useState({}); @@ -87,8 +89,8 @@ const PluginPage: React.FC = ({ }); fetchPluginTemplateList().then((data) => { setPluginTemplateList(data); - form.setFieldsValue({ plugin_config_id }) - }) + form.setFieldsValue({ plugin_config_id }); + }); }, []); const PluginList = () => ( @@ -112,7 +114,11 @@ const PluginPage: React.FC = ({ {typeList.map((typeItem) => { return ( - + ); })} @@ -149,7 +155,9 @@ const PluginPage: React.FC = ({ {[ { id: '', - desc: formatMessage({ id: 'component.step.select.pluginTemplate.select.option' }), + desc: formatMessage({ + id: 'component.step.select.pluginTemplate.select.option', + }), }, ...pluginTemplateList, ].map((item) => ( @@ -160,10 +168,15 @@ const PluginPage: React.FC = ({ - -

{formatMessage({ id: 'component.plugin.pluginTemplate.tip1' })}

-

{formatMessage({ id: 'component.plugin.pluginTemplate.tip2' })}

- } type="info" /> + +

{formatMessage({ id: 'component.plugin.pluginTemplate.tip1' })}

+

{formatMessage({ id: 'component.plugin.pluginTemplate.tip2' })}

+ + } + type="info" + /> )} {typeList.map((typeItem) => { @@ -183,17 +196,19 @@ const PluginPage: React.FC = ({ key={item.name} actions={[ , ]} title={[ diff --git a/web/src/components/Plugin/UI/api-breaker.tsx b/web/src/components/Plugin/UI/api-breaker.tsx index 28f851846d..f86a9bb237 100644 --- a/web/src/components/Plugin/UI/api-breaker.tsx +++ b/web/src/components/Plugin/UI/api-breaker.tsx @@ -29,7 +29,7 @@ const FORM_ITEM_LAYOUT = { span: 7, }, wrapperCol: { - span: 7 + span: 7, }, }; @@ -40,7 +40,7 @@ const FORM_ITEM_WITHOUT_LABEL = { }; const ApiBreaker: React.FC = ({ form }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return (
= ({ form }) => { @@ -78,14 +82,12 @@ const ApiBreaker: React.FC = ({ form }) => { - + {fields.length > 1 ? ( @@ -120,7 +122,9 @@ const ApiBreaker: React.FC = ({ form }) => { label="unhealthy.failures" name={['unhealthy', 'failures']} initialValue={3} - tooltip={formatMessage({ id: 'component.pluginForm.api-breaker.unhealthy.failures.tooltip' })} + tooltip={formatMessage({ + id: 'component.pluginForm.api-breaker.unhealthy.failures.tooltip', + })} > @@ -134,13 +138,11 @@ const ApiBreaker: React.FC = ({ form }) => { {...(index === 0 ? FORM_ITEM_LAYOUT : FORM_ITEM_WITHOUT_LABEL)} key={field.key} label={index === 0 && 'healthy.http_statuses'} - tooltip={formatMessage({ id: 'component.pluginForm.api-breaker.healthy.http_statuses.tooltip' })} + tooltip={formatMessage({ + id: 'component.pluginForm.api-breaker.healthy.http_statuses.tooltip', + })} > - + {fields.length > 1 ? ( @@ -175,12 +177,14 @@ const ApiBreaker: React.FC = ({ form }) => { label="healthy.successes" name={['healthy', 'successes']} initialValue={3} - tooltip={formatMessage({ id: 'component.pluginForm.api-breaker.healthy.successes.tooltip' })} + tooltip={formatMessage({ + id: 'component.pluginForm.api-breaker.healthy.successes.tooltip', + })} > - + ); -} +}; export default ApiBreaker; diff --git a/web/src/components/Plugin/UI/basic-auth.tsx b/web/src/components/Plugin/UI/basic-auth.tsx index 8d95aa0bdd..8613b89095 100644 --- a/web/src/components/Plugin/UI/basic-auth.tsx +++ b/web/src/components/Plugin/UI/basic-auth.tsx @@ -28,32 +28,21 @@ export const FORM_ITEM_LAYOUT = { span: 4, }, wrapperCol: { - span: 8 + span: 8, }, }; const BasicAuth: React.FC = ({ form }) => { return ( -
- + + - + ); -} +}; export default BasicAuth; diff --git a/web/src/components/Plugin/UI/cors.tsx b/web/src/components/Plugin/UI/cors.tsx index a052d078b2..12f5e39aab 100644 --- a/web/src/components/Plugin/UI/cors.tsx +++ b/web/src/components/Plugin/UI/cors.tsx @@ -30,7 +30,7 @@ const FORM_ITEM_LAYOUT = { span: 7, }, wrapperCol: { - span: 8 + span: 8, }, }; @@ -50,10 +50,7 @@ const Cors: React.FC = ({ form }) => { > - + - +
); return ( -
+ = ({ form }) => { - + {(fields, { add, remove }) => { return (
@@ -134,13 +143,11 @@ const Cors: React.FC = ({ form }) => { {...(index === 0 ? FORM_ITEM_LAYOUT : FORM_ITEM_WITHOUT_LABEL)} label={index === 0 && 'allow_origins_by_regex'} key={field.key} - tooltip={formatMessage({ id: 'component.pluginForm.cors.allow_origins_by_regex.tooltip' })} + tooltip={formatMessage({ + id: 'component.pluginForm.cors.allow_origins_by_regex.tooltip', + })} > - + {fields.length > 1 ? ( @@ -171,8 +178,8 @@ const Cors: React.FC = ({ form }) => { ); }} - + ); -} +}; export default Cors; diff --git a/web/src/components/Plugin/UI/limit-conn.tsx b/web/src/components/Plugin/UI/limit-conn.tsx index ec535fc889..558ed39cc1 100644 --- a/web/src/components/Plugin/UI/limit-conn.tsx +++ b/web/src/components/Plugin/UI/limit-conn.tsx @@ -29,17 +29,14 @@ const FORM_ITEM_LAYOUT = { span: 6, }, wrapperCol: { - span: 8 + span: 8, }, }; const LimitConn: React.FC = ({ form }) => { const { formatMessage } = useIntl(); return ( -
+ = ({ form }) => { label="default_conn_delay" required name="default_conn_delay" - tooltip={formatMessage({ id: 'component.pluginForm.limit-conn.default_conn_delay.tooltip' })} + tooltip={formatMessage({ + id: 'component.pluginForm.limit-conn.default_conn_delay.tooltip', + })} > @@ -72,8 +71,18 @@ const LimitConn: React.FC = ({ form }) => { tooltip={formatMessage({ id: 'component.pluginForm.limit-conn.key.tooltip' })} > @@ -88,6 +97,6 @@ const LimitConn: React.FC = ({ form }) => { ); -} +}; export default LimitConn; diff --git a/web/src/components/Plugin/UI/limit-count.tsx b/web/src/components/Plugin/UI/limit-count.tsx index cf86a2e0c9..e18b841a72 100644 --- a/web/src/components/Plugin/UI/limit-count.tsx +++ b/web/src/components/Plugin/UI/limit-count.tsx @@ -24,20 +24,21 @@ type Props = { form: FormInstance; }; -type PolicyProps = "local" | "redis" | "redis-cluster" +type PolicyProps = 'local' | 'redis' | 'redis-cluster'; const FORM_ITEM_LAYOUT = { labelCol: { span: 7, }, wrapperCol: { - span: 10 + span: 10, }, }; const FORM_ITEM_WITHOUT_LABEL = { wrapperCol: { - span: 10, offset: 7, + span: 10, + offset: 7, }, }; @@ -50,54 +51,69 @@ const removeBtnStyle = { const RedisForm: React.FC = () => { const { formatMessage } = useIntl(); - return (<> - - - - - - - - - - - - - - - - ) -} + return ( + <> + + + + + + + + + + + + + + + + + ); +}; const RedisClusterForm: React.FC = () => { const { formatMessage } = useIntl(); @@ -108,8 +124,15 @@ const RedisClusterForm: React.FC = () => { label="redis_cluster_name" name="redis_cluster_name" validateTrigger={['onChange', 'onBlur', 'onClick']} - rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_name` }]} - tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })} + rules={[ + { + required: true, + message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_name`, + }, + ]} + tooltip={formatMessage({ + id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip', + })} >
@@ -118,10 +141,12 @@ const RedisClusterForm: React.FC = () => { return (
{fields.map((field, index) => ( @@ -130,7 +155,20 @@ const RedisClusterForm: React.FC = () => { {...field} noStyle validateTrigger={['onChange', 'onBlur', 'onClick']} - rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_node` }, { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }]} + rules={[ + { + required: true, + message: `${formatMessage({ + id: 'component.global.pleaseEnter', + })} redis_cluster_node`, + }, + { + min: 2, + message: formatMessage({ + id: 'component.pluginForm.limit-count.atLeast2Characters.rule', + }), + }, + ]} > @@ -178,22 +216,25 @@ const RedisClusterForm: React.FC = () => { > - ) -} + + ); +}; const LimitCount: React.FC = ({ form }) => { const [policy, setPoicy] = useState('local'); - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( -
+ @@ -202,20 +243,36 @@ const LimitCount: React.FC = ({ form }) => { = ({ form }) => { name="policy" tooltip={formatMessage({ id: 'component.pluginForm.limit-count.policy.tooltip' })} > - { + setPoicy(e); + }} + > + {['local', 'redis', 'redis-cluster'].map((item) => ( + + {item} + + ))} - prev.policy !== next.policy} style={{ display: 'none' }}> + prev.policy !== next.policy} + style={{ display: 'none' }} + > {() => { setPoicy(form.getFieldValue('policy')); }} @@ -245,6 +313,6 @@ const LimitCount: React.FC = ({ form }) => { {Boolean(policy === 'redis-cluster') && } ); -} +}; export default LimitCount; diff --git a/web/src/components/Plugin/UI/limit-req.tsx b/web/src/components/Plugin/UI/limit-req.tsx index 7f106a4554..13318dc65e 100644 --- a/web/src/components/Plugin/UI/limit-req.tsx +++ b/web/src/components/Plugin/UI/limit-req.tsx @@ -30,7 +30,7 @@ export const FORM_ITEM_LAYOUT = { span: 4, }, wrapperCol: { - span: 8 + span: 8, }, }; @@ -38,17 +38,16 @@ const LimitReq: React.FC = ({ form, schema }) => { const { formatMessage } = useIntl(); const propertires = schema?.properties; return ( -
+ @@ -57,10 +56,12 @@ const LimitReq: React.FC = ({ form, schema }) => { @@ -69,16 +70,22 @@ const LimitReq: React.FC = ({ form, schema }) => { @@ -88,10 +95,13 @@ const LimitReq: React.FC = ({ form, schema }) => { initialValue={propertires.rejected_code.default} tooltip={formatMessage({ id: 'component.pluginForm.limit-req.rejected_code.tooltip' })} > - + ); -} +}; export default LimitReq; diff --git a/web/src/components/Plugin/UI/plugin.tsx b/web/src/components/Plugin/UI/plugin.tsx index d937e2e025..d0ea0de869 100644 --- a/web/src/components/Plugin/UI/plugin.tsx +++ b/web/src/components/Plugin/UI/plugin.tsx @@ -29,38 +29,53 @@ import RefererRestriction from './referer-restriction'; import Cors from './cors'; type Props = { - name: string, - schema: Record | undefined, - form: FormInstance, - renderForm: boolean -} + name: string; + schema: Record | undefined; + form: FormInstance; + renderForm: boolean; +}; -export const PLUGIN_UI_LIST = ['api-breaker', 'basic-auth', 'cors', 'limit-req', 'limit-conn', 'proxy-mirror', 'referer-restriction', 'limit-count']; +export const PLUGIN_UI_LIST = [ + 'api-breaker', + 'basic-auth', + 'cors', + 'limit-req', + 'limit-conn', + 'proxy-mirror', + 'referer-restriction', + 'limit-count', +]; export const PluginForm: React.FC = ({ name, schema, renderForm, form }) => { - const { formatMessage } = useIntl(); - if (!renderForm) { return }; + if (!renderForm) { + return ( + + ); + } switch (name) { case 'api-breaker': - return + return ; case 'basic-auth': - return + return ; case 'limit-count': - return + return ; case 'cors': - return + return ; case 'limit-req': - return + return ; case 'proxy-mirror': - return + return ; case 'limit-conn': - return + return ; case 'referer-restriction': - return + return ; default: return null; } -} +}; diff --git a/web/src/components/Plugin/UI/proxy-mirror.tsx b/web/src/components/Plugin/UI/proxy-mirror.tsx index aa5db8f7a9..e1e9fb051b 100644 --- a/web/src/components/Plugin/UI/proxy-mirror.tsx +++ b/web/src/components/Plugin/UI/proxy-mirror.tsx @@ -28,7 +28,7 @@ const FORM_ITEM_LAYOUT = { span: 4, }, wrapperCol: { - span: 10 + span: 10, }, }; @@ -36,10 +36,7 @@ const ProxyMirror: React.FC = ({ form }) => { const { formatMessage } = useIntl(); return ( -
+ = ({ form }) => { tooltip={formatMessage({ id: 'component.pluginForm.proxy-mirror.host.tooltip' })} rules={[ { - pattern: new RegExp(/^http(s)?:\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:[0-9]{1,5})?$/, 'g'), + pattern: new RegExp( + /^http(s)?:\/\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:[0-9]{1,5})?$/, + 'g', + ), message: formatMessage({ id: 'component.pluginForm.proxy-mirror.host.ruletip' }), - } + }, ]} >
); -} +}; export default ProxyMirror; diff --git a/web/src/components/Plugin/UI/referer-restriction.tsx b/web/src/components/Plugin/UI/referer-restriction.tsx index 0e527a1e9b..3083ac8955 100644 --- a/web/src/components/Plugin/UI/referer-restriction.tsx +++ b/web/src/components/Plugin/UI/referer-restriction.tsx @@ -29,13 +29,14 @@ const FORM_ITEM_LAYOUT = { span: 5, }, wrapperCol: { - span: 18 + span: 18, }, }; const FORM_ITEM_WITHOUT_LABEL = { wrapperCol: { - span: 10, offset: 5 + span: 10, + offset: 5, }, }; @@ -46,21 +47,21 @@ const removeBtnStyle = { }; const RefererRestriction: React.FC = ({ form }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( -
+ {(fields, { add, remove }) => { return (
@@ -72,15 +73,20 @@ const RefererRestriction: React.FC = ({ form }) => { validateTrigger={['onChange', 'onBlur', 'onClick']} noStyle required - rules={[{ - message: formatMessage({ - id: 'page.route.form.itemRulesPatternMessage.domain', - }), - pattern: new RegExp(/^\*?[0-9a-zA-Z-._]+$/, 'g') - }, { - required: true, - message: `${formatMessage({ id: 'component.global.pleaseEnter' })} whitelist` - }]} + rules={[ + { + message: formatMessage({ + id: 'page.route.form.itemRulesPatternMessage.domain', + }), + pattern: new RegExp(/^\*?[0-9a-zA-Z-._]+$/, 'g'), + }, + { + required: true, + message: `${formatMessage({ + id: 'component.global.pleaseEnter', + })} whitelist`, + }, + ]} > @@ -113,16 +119,20 @@ const RefererRestriction: React.FC = ({ form }) => { }} - + ); -} +}; export default RefererRestriction; diff --git a/web/src/components/Plugin/data.tsx b/web/src/components/Plugin/data.tsx index 7281ea1e0c..1cfd297e19 100644 --- a/web/src/components/Plugin/data.tsx +++ b/web/src/components/Plugin/data.tsx @@ -27,7 +27,7 @@ export const PLUGIN_ICON_LIST: Record = { 'kafka-logger': , 'basic-auth': , 'hmac-auth': , - 'cors': , + cors: , 'wolf-rbac': , 'key-auth': , 'request-validation': , @@ -49,13 +49,13 @@ export const PLUGIN_ICON_LIST: Record = { 'proxy-cache': , 'grpc-transcode': , 'batch-requests': , - 'zipkin': , + zipkin: , 'udp-logger': , 'error-log-logger': , 'http-logger': , 'request-id': , 'sls-logger': , - 'syslog': , + syslog: , 'tcp-logger': , }; @@ -66,162 +66,162 @@ export const PLUGIN_FILTER_LIST: Record { if (cached.list.length) { - return Promise.resolve(cached.list) + return Promise.resolve(cached.list); } return request>('/plugins?all=true').then((data) => { - const typedData = data.data.map(item => ({ + const typedData = data.data.map((item) => ({ ...item, - type: PLUGIN_LIST[item.name]?.type || "other", + type: PLUGIN_LIST[item.name]?.type || 'other', originType: item.type, - hidden: PLUGIN_LIST[item.name]?.hidden || false + hidden: PLUGIN_LIST[item.name]?.hidden || false, })); - let finalList: PluginComponent.Meta[] = [] + let finalList: PluginComponent.Meta[] = []; - Object.values(PluginType).forEach(type => { - finalList = finalList.concat(typedData.filter(item => item.type === type)) - }) + Object.values(PluginType).forEach((type) => { + finalList = finalList.concat(typedData.filter((item) => item.type === type)); + }); if (cached.list.length === 0) { - cached.list = finalList + cached.list = finalList; } - return finalList + return finalList; }); }; @@ -82,7 +82,9 @@ export const fetchSchema = async ( }; export const fetchPluginTemplateList = () => { - return request>>('/plugin_configs').then((data) => { - return data.data.rows; - }); + return request>>('/plugin_configs').then( + (data) => { + return data.data.rows; + }, + ); }; diff --git a/web/src/components/Plugin/typing.d.ts b/web/src/components/Plugin/typing.d.ts index c6400f1c76..7dd46d6568 100644 --- a/web/src/components/Plugin/typing.d.ts +++ b/web/src/components/Plugin/typing.d.ts @@ -24,7 +24,7 @@ declare namespace PluginComponent { priority: number; schema: Record; type: string; - originType: string, + originType: string; version: number; consumer_schema?: Record; hidden?: boolean; @@ -36,7 +36,7 @@ declare namespace PluginComponent { formData: any; monacoData: any; shouldDelete?: boolean; - } + }; type MonacoLanguage = 'JSON' | 'YAML' | 'Form'; } diff --git a/web/src/components/PluginFlow/PluginFlow.tsx b/web/src/components/PluginFlow/PluginFlow.tsx index 21afb12263..7794139def 100644 --- a/web/src/components/PluginFlow/PluginFlow.tsx +++ b/web/src/components/PluginFlow/PluginFlow.tsx @@ -14,190 +14,213 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useEffect, useState } from 'react' -import { Modal, Form, Input, Alert } from 'antd' -import { Cell } from '@antv/x6' -import { useIntl } from 'umi' - -import FlowGraph from './components/FlowGraph' -import Toolbar from './components/Toolbar' -import { DEFAULT_CONDITION_PROPS, DEFAULT_PLUGIN_PROPS, DEFAULT_STENCIL_WIDTH, DEFAULT_TOOLBAR_HEIGHT, FlowGraphEvent } from './constants' -import styles from './style.less' -import PluginDetail from '../Plugin/PluginDetail' -import { fetchList } from '../Plugin/service' +import React, { useEffect, useState } from 'react'; +import { Modal, Form, Input, Alert } from 'antd'; +import { Cell } from '@antv/x6'; +import { useIntl } from 'umi'; + +import FlowGraph from './components/FlowGraph'; +import Toolbar from './components/Toolbar'; +import { + DEFAULT_CONDITION_PROPS, + DEFAULT_PLUGIN_PROPS, + DEFAULT_STENCIL_WIDTH, + DEFAULT_TOOLBAR_HEIGHT, + FlowGraphEvent, +} from './constants'; +import styles from './style.less'; +import PluginDetail from '../Plugin/PluginDetail'; +import { fetchList } from '../Plugin/service'; type Props = { chart: { cells: Cell.Properties[]; }; readonly?: boolean; -} +}; type PluginProps = { id: string; name: string; visible: boolean; data: any; -} +}; type ConditionProps = { id: string; visible: boolean; data: string; -} +}; const PluginFlow: React.FC = ({ chart, readonly = false }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); // NOTE: To prevent from graph is not initialized - const [isReady, setIsReady] = useState(false) - const [plugins, setPlugins] = useState([]) + const [isReady, setIsReady] = useState(false); + const [plugins, setPlugins] = useState([]); - const [pluginProps, setPluginProps] = useState(DEFAULT_PLUGIN_PROPS) - const [conditionProps, setConditionProps] = useState(DEFAULT_CONDITION_PROPS) + const [pluginProps, setPluginProps] = useState(DEFAULT_PLUGIN_PROPS); + const [conditionProps, setConditionProps] = useState(DEFAULT_CONDITION_PROPS); const getContainerSize = () => { - const leftSidebar = document.querySelector('aside.ant-layout-sider') - const blankSpaceWidth = 24 * 4 + const leftSidebar = document.querySelector('aside.ant-layout-sider'); + const blankSpaceWidth = 24 * 4; - const globalHeaderHeight = 48 - const pageHeaderHeight = 72 - const otherHeight = 191 + const globalHeaderHeight = 48; + const pageHeaderHeight = 72; + const otherHeight = 191; - const width = document.body.offsetWidth - (leftSidebar?.clientWidth || 0) - blankSpaceWidth - DEFAULT_STENCIL_WIDTH - const height = document.body.offsetHeight - globalHeaderHeight - pageHeaderHeight - otherHeight + const width = + document.body.offsetWidth - + (leftSidebar?.clientWidth || 0) - + blankSpaceWidth - + DEFAULT_STENCIL_WIDTH; + const height = document.body.offsetHeight - globalHeaderHeight - pageHeaderHeight - otherHeight; return { width, - height: height < 800 ? 800 : height - } - } + height: height < 800 ? 800 : height, + }; + }; useEffect(() => { if (!plugins.length) { - return + return; } - const container = document.getElementById("container") + const container = document.getElementById('container'); if (!container) { - return + return; } - const siderbarCollapsedButton = document.querySelector('.ant-pro-sider-collapsed-button') + const siderbarCollapsedButton = document.querySelector('.ant-pro-sider-collapsed-button'); const graph = FlowGraph.init(container, plugins, chart); - (window as any).graph = FlowGraph - setIsReady(true) + (window as any).graph = FlowGraph; + setIsReady(true); - const stencilContainer = document.querySelector('#stencil') as HTMLElement + const stencilContainer = document.querySelector('#stencil') as HTMLElement; const handleResize = () => { - const { width, height } = getContainerSize() - graph.resize(width, height) + const { width, height } = getContainerSize(); + graph.resize(width, height); - stencilContainer.style.height = `${height + DEFAULT_TOOLBAR_HEIGHT}px` - stencilContainer.style.width = `${DEFAULT_STENCIL_WIDTH}px` - } + stencilContainer.style.height = `${height + DEFAULT_TOOLBAR_HEIGHT}px`; + stencilContainer.style.width = `${DEFAULT_STENCIL_WIDTH}px`; + }; const handleLeftSidebarResize = () => { setTimeout(() => { - handleResize() - }, 200) - } + handleResize(); + }, 200); + }; - handleResize() + handleResize(); - graph.on(FlowGraphEvent.PLUGIN_CHANGE, setPluginProps) + graph.on(FlowGraphEvent.PLUGIN_CHANGE, setPluginProps); graph.on(FlowGraphEvent.CONDITION_CHANGE, (props: ConditionProps) => { - setConditionProps(props) - }) + setConditionProps(props); + }); if (readonly) { - graph.disableKeyboard() + graph.disableKeyboard(); } - window.addEventListener("resize", handleResize) - siderbarCollapsedButton?.addEventListener('click', handleLeftSidebarResize) + window.addEventListener('resize', handleResize); + siderbarCollapsedButton?.addEventListener('click', handleLeftSidebarResize); // eslint-disable-next-line return () => { - window.removeEventListener("resize", handleResize) - siderbarCollapsedButton?.removeEventListener('click', handleLeftSidebarResize) - } - }, [plugins]) + window.removeEventListener('resize', handleResize); + siderbarCollapsedButton?.removeEventListener('click', handleLeftSidebarResize); + }; + }, [plugins]); useEffect(() => { - fetchList().then(setPlugins) - }, []) + fetchList().then(setPlugins); + }, []); return ( - {readonly && } + {readonly && ( + + )}
-
+
{isReady && }
- { - pluginProps.visible && ( - { - setPluginProps(DEFAULT_PLUGIN_PROPS) - }} - onChange={({ formData, monacoData, shouldDelete }) => { - if (shouldDelete) { - FlowGraph.graph.removeCell(pluginProps.id) - } else { - const disable = !formData.disable - FlowGraph.setData(pluginProps.id, { ...monacoData, disable }) - } - setPluginProps(DEFAULT_PLUGIN_PROPS) - }} - /> - ) - } + {pluginProps.visible && ( + { + setPluginProps(DEFAULT_PLUGIN_PROPS); + }} + onChange={({ formData, monacoData, shouldDelete }) => { + if (shouldDelete) { + FlowGraph.graph.removeCell(pluginProps.id); + } else { + const disable = !formData.disable; + FlowGraph.setData(pluginProps.id, { ...monacoData, disable }); + } + setPluginProps(DEFAULT_PLUGIN_PROPS); + }} + /> + )} { FlowGraph.setData(conditionProps.id, conditionProps.data); - setConditionProps(DEFAULT_CONDITION_PROPS) + setConditionProps(DEFAULT_CONDITION_PROPS); }} onCancel={() => setConditionProps(DEFAULT_CONDITION_PROPS)} okText={formatMessage({ id: 'component.global.confirm' })} cancelText={formatMessage({ id: 'component.global.cancel' })} okButtonProps={{ - disabled: readonly + disabled: readonly, }} > - + { + onChange={(e) => { setConditionProps({ ...conditionProps, - data: e.target.value - }) + data: e.target.value, + }); }} /> - ) -} + ); +}; -export default PluginFlow +export default PluginFlow; diff --git a/web/src/components/PluginFlow/components/FlowGraph/FlowGraph.ts b/web/src/components/PluginFlow/components/FlowGraph/FlowGraph.ts index af9fc32647..cb3592018b 100644 --- a/web/src/components/PluginFlow/components/FlowGraph/FlowGraph.ts +++ b/web/src/components/PluginFlow/components/FlowGraph/FlowGraph.ts @@ -14,54 +14,66 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Graph, Addon, FunctionExt } from '@antv/x6' -import type { Model, Cell } from '@antv/x6' -import { formatMessage } from 'umi' -import { notification } from 'antd' - -import './shapes' -import { DEFAULT_OPINIONS, DEFAULT_PLUGIN_FLOW_DATA, DEFAULT_STENCIL_OPINIONS, FlowGraphEvent, FlowGraphShape } from '../../constants' +import { Graph, Addon, FunctionExt } from '@antv/x6'; +import type { Model, Cell } from '@antv/x6'; +import { formatMessage } from 'umi'; +import { notification } from 'antd'; + +import './shapes'; +import { + DEFAULT_OPINIONS, + DEFAULT_PLUGIN_FLOW_DATA, + DEFAULT_STENCIL_OPINIONS, + FlowGraphEvent, + FlowGraphShape, +} from '../../constants'; class FlowGraph { - public static graph: Graph - private static stencil: Addon.Stencil - private static pluginTypeList: string[] = [] - private static plugins: PluginComponent.Meta[] = [] - - public static init(container: HTMLElement, plugins: PluginComponent.Meta[] = [], chart: Model.FromJSONData) { + public static graph: Graph; + private static stencil: Addon.Stencil; + private static pluginTypeList: string[] = []; + private static plugins: PluginComponent.Meta[] = []; + + public static init( + container: HTMLElement, + plugins: PluginComponent.Meta[] = [], + chart: Model.FromJSONData, + ) { this.graph = new Graph({ container, - ...DEFAULT_OPINIONS - }) + ...DEFAULT_OPINIONS, + }); - this.plugins = plugins - this.pluginTypeList = Array.from(new Set(plugins.map(item => item.type))) + this.plugins = plugins; + this.pluginTypeList = Array.from(new Set(plugins.map((item) => item.type))); - this.initStencil() - this.initShape() - this.initGraphShape(chart) - this.initEvent() - return this.graph + this.initStencil(); + this.initShape(); + this.initGraphShape(chart); + this.initEvent(); + return this.graph; } // NOTE: set cell data according to Cell ID public static setData(id: string, data: any): void { - const cell = this.graph.getCell(id) + const cell = this.graph.getCell(id); if (cell) { - cell.setData(data, { overwrite: true }) + cell.setData(data, { overwrite: true }); } } // NOTE: Generate groups for stencil private static generateGroups(): Addon.Stencil.Group[] { - const otherGroupList = [{ - name: 'basic', - title: formatMessage({ id: 'component.plugin-flow.text.general' }), - graphHeight: 104, - }] - - const pluginGroupList = this.pluginTypeList.map(item => { - const count = this.plugins.filter(plugin => plugin.type === item).length + const otherGroupList = [ + { + name: 'basic', + title: formatMessage({ id: 'component.plugin-flow.text.general' }), + graphHeight: 104, + }, + ]; + + const pluginGroupList = this.pluginTypeList.map((item) => { + const count = this.plugins.filter((plugin) => plugin.type === item).length; return { name: item, title: formatMessage({ id: `component.plugin.${item}` }), @@ -70,24 +82,24 @@ class FlowGraph { marginX: 60, }, graphHeight: count * 82, - } - }) + }; + }); - return otherGroupList.concat(pluginGroupList) + return otherGroupList.concat(pluginGroupList); } private static initStencil() { this.stencil = new Addon.Stencil({ target: this.graph, ...DEFAULT_STENCIL_OPINIONS, - groups: this.generateGroups() - }) - const stencilContainer = document.querySelector('#stencil') - stencilContainer?.appendChild(this.stencil.container) + groups: this.generateGroups(), + }); + const stencilContainer = document.querySelector('#stencil'); + stencilContainer?.appendChild(this.stencil.container); } private static initShape() { - const { graph } = this + const { graph } = this; const r1 = graph.createNode({ shape: FlowGraphShape.start, attrs: { @@ -101,7 +113,7 @@ class FlowGraph { }, }, }, - }) + }); const r3 = graph.createNode({ shape: FlowGraphShape.condition, @@ -152,243 +164,259 @@ class FlowGraph { }, }, }, - }) - - this.stencil.load([r1, r3], 'basic') - this.pluginTypeList.forEach(type => { - const plugins = this.plugins.filter(plugin => plugin.type === type).map(plugin => { - return graph.createNode({ - shape: FlowGraphShape.plugin, - attrs: { - title: { - text: plugin.name + }); + + this.stencil.load([r1, r3], 'basic'); + this.pluginTypeList.forEach((type) => { + const plugins = this.plugins + .filter((plugin) => plugin.type === type) + .map((plugin) => { + return graph.createNode({ + shape: FlowGraphShape.plugin, + attrs: { + title: { + text: plugin.name, + }, + text: { + text: plugin.name, + }, }, - text: { - text: plugin.name - } - } - }) - }) + }); + }); - this.stencil.load(plugins, type) - }) + this.stencil.load(plugins, type); + }); } private static initGraphShape(chart: Model.FromJSONData) { if (!chart) { - return + return; } - this.graph.fromJSON(chart) + this.graph.fromJSON(chart); } private static showPorts(ports: NodeListOf, show: boolean) { // eslint-disable-next-line for (let i = 0, len = ports.length; i < len; i = i + 1) { // eslint-disable-next-line - ports[i].style.visibility = show ? 'visible' : 'hidden' + ports[i].style.visibility = show ? 'visible' : 'hidden'; } } private static initEvent() { - const { graph } = this - const container = document.getElementById('container')! + const { graph } = this; + const container = document.getElementById('container')!; graph.on( 'node:mouseenter', FunctionExt.debounce(() => { - const ports = container.querySelectorAll( - '.x6-port-body', - ) as NodeListOf - this.showPorts(ports, true) + const ports = container.querySelectorAll('.x6-port-body') as NodeListOf; + this.showPorts(ports, true); }), 500, - ) + ); graph.on('node:mouseleave', () => { - const ports = container.querySelectorAll( - '.x6-port-body', - ) as NodeListOf - this.showPorts(ports, false) - }) + const ports = container.querySelectorAll('.x6-port-body') as NodeListOf; + this.showPorts(ports, false); + }); graph.on('node:dblclick', ({ node }) => { if (node.shape === FlowGraphShape.plugin) { - const name = node.getAttrByPath('text/text') as string + const name = node.getAttrByPath('text/text') as string; if (!name) { - return + return; } this.graph.trigger(FlowGraphEvent.PLUGIN_CHANGE, { visible: true, id: node.id, name, - data: node.getData() - }) + data: node.getData(), + }); } if (node.shape === FlowGraphShape.condition) { this.graph.trigger(FlowGraphEvent.CONDITION_CHANGE, { id: node.id, data: node.getData(), - visible: true - }) + visible: true, + }); } - }) + }); graph.bindKey('backspace', () => { - const cells = graph.getSelectedCells() + const cells = graph.getSelectedCells(); if (cells.length) { - graph.removeCells(cells) + graph.removeCells(cells); } - }) + }); } private static getNextCell(id = '', position = ''): Cell.Properties | undefined { - const { cells = [] } = this.graph.toJSON() - const cell = cells.find(item => item.id === id) + const { cells = [] } = this.graph.toJSON(); + const cell = cells.find((item) => item.id === id); if (!cell) { - return undefined + return undefined; } if (!cell.ports) { - return undefined + return undefined; } - const port = cell.ports.items.find((item: { group: string }) => item.group === position) + const port = cell.ports.items.find((item: { group: string }) => item.group === position); if (!port) { - return undefined + return undefined; } - const targetCellId = cells.find(item => item.source?.port === port.id && item.source?.cell === id)?.target.cell - const targetCell = cells.find(item => item.id === targetCellId) - return targetCell + const targetCellId = cells.find( + (item) => item.source?.port === port.id && item.source?.cell === id, + )?.target.cell; + const targetCell = cells.find((item) => item.id === targetCellId); + return targetCell; } private static getLeafList(currentId = '') { - let ids: string[] = [] + let ids: string[] = []; const fn = (id: string) => { - const cell = this.getNextCell(id, "right") + const cell = this.getNextCell(id, 'right'); if (!cell || !cell.id) { - return + return; } ids = ids.concat(cell.id); - fn(cell.id) - } + fn(cell.id); + }; - fn(currentId) - return [currentId].concat(ids) + fn(currentId); + return [currentId].concat(ids); } /** * Convert Graph JSON Data to API Request Body Data - */ - public static convertToData(chart: typeof DEFAULT_PLUGIN_FLOW_DATA.chart | undefined = undefined): { - chart: { - cells: Cell.Properties[]; - }; - conf: Record; - rule: Record; - } | undefined { + */ + public static convertToData( + chart: typeof DEFAULT_PLUGIN_FLOW_DATA.chart | undefined = undefined, + ): + | { + chart: { + cells: Cell.Properties[]; + }; + conf: Record; + rule: Record; + } + | undefined { const data = { ...DEFAULT_PLUGIN_FLOW_DATA, - chart: chart || this.graph.toJSON() - } + chart: chart || this.graph.toJSON(), + }; - const { cells = [] } = data.chart + const { cells = [] } = data.chart; - const edgeCells = cells.filter(cell => cell.shape === 'edge') + const edgeCells = cells.filter((cell) => cell.shape === 'edge'); - const startCell = cells.find(cell => cell.shape === FlowGraphShape.start) + const startCell = cells.find((cell) => cell.shape === FlowGraphShape.start); if (!startCell) { notification.warn({ - message: formatMessage({ id: 'component.plugin-flow.text.no-start-node' }) - }) - return + message: formatMessage({ id: 'component.plugin-flow.text.no-start-node' }), + }); + return; } - const rootCell = cells.find(cell => cell.shape === 'edge' && cell.source.cell === startCell.id) + const rootCell = cells.find( + (cell) => cell.shape === 'edge' && cell.source.cell === startCell.id, + ); if (!rootCell) { notification.warn({ - message: formatMessage({ id: 'component.plugin-flow.text.no-root-node' }) - }) - return + message: formatMessage({ id: 'component.plugin-flow.text.no-root-node' }), + }); + return; } - data.rule.root = rootCell.target.cell + data.rule.root = rootCell.target.cell; // Get the ID associated with each node, the relationship between nodes is in edgeCells. - edgeCells.forEach(edge => { - const sourceId = edge.source.cell - const targetId = edge.target.cell + edgeCells.forEach((edge) => { + const sourceId = edge.source.cell; + const targetId = edge.target.cell; - data.rule[sourceId] = [] + data.rule[sourceId] = []; - this.getLeafList(targetId).forEach(id => { - const cell = cells.find(item => item.id === id) + this.getLeafList(targetId).forEach((id) => { + const cell = cells.find((item) => item.id === id); if (!cell) { - return + return; } if (cell.shape === FlowGraphShape.condition) { - const nextCell = this.getNextCell(cell.id, "bottom"); + const nextCell = this.getNextCell(cell.id, 'bottom'); if (!nextCell) { - return + return; } - data.rule[sourceId].push([cell.data, nextCell.id]) + data.rule[sourceId].push([cell.data, nextCell.id]); } if (cell.shape === FlowGraphShape.plugin) { - data.rule[sourceId].push(['', cell.id]) + data.rule[sourceId].push(['', cell.id]); } - }) - }) + }); + }); // NOTE: Omit empty array, or API will throw error. Object.entries(data.rule).forEach(([key, value]) => { if (value.length === 0) { - delete data.rule[key] + delete data.rule[key]; } if (key === 'root') { - return + return; } - const cell = cells.find(item => item.id === key) + const cell = cells.find((item) => item.id === key); if (cell?.shape !== FlowGraphShape.plugin) { - delete data.rule[key] + delete data.rule[key]; } - }) + }); - const invalidPluginCell = cells.find(item => item.shape === FlowGraphShape.plugin && !item.data) + const invalidPluginCell = cells.find( + (item) => item.shape === FlowGraphShape.plugin && !item.data, + ); if (invalidPluginCell) { notification.warn({ message: formatMessage({ id: 'component.plugin-flow.text.without-data' }), - description: `${formatMessage({ id: 'component.plugin-flow.text.plugin-without-data.description' })}${invalidPluginCell.attrs?.text.text}` - }) - return + description: `${formatMessage({ + id: 'component.plugin-flow.text.plugin-without-data.description', + })}${invalidPluginCell.attrs?.text.text}`, + }); + return; } - const invalidConditionCell = cells.find(item => item.shape === FlowGraphShape.condition && !item.data) + const invalidConditionCell = cells.find( + (item) => item.shape === FlowGraphShape.condition && !item.data, + ); if (invalidConditionCell) { notification.warn({ message: formatMessage({ id: 'component.plugin-flow.text.without-data' }), - description: `${formatMessage({ id: 'component.plugin-flow.text.condition-without-configuration' })}` - }) - return + description: `${formatMessage({ + id: 'component.plugin-flow.text.condition-without-configuration', + })}`, + }); + return; } - data.conf = {} - cells.filter(item => item.shape === FlowGraphShape.plugin && item.id).forEach(item => { - if (item.id) { - data.conf[item.id] = { - name: item.attrs?.text.text, - conf: item.data + data.conf = {}; + cells + .filter((item) => item.shape === FlowGraphShape.plugin && item.id) + .forEach((item) => { + if (item.id) { + data.conf[item.id] = { + name: item.attrs?.text.text, + conf: item.data, + }; } - } - }) + }); // eslint-disable-next-line - return data + return data; } } -export default FlowGraph +export default FlowGraph; diff --git a/web/src/components/PluginFlow/components/FlowGraph/index.ts b/web/src/components/PluginFlow/components/FlowGraph/index.ts index 5dc41d5fc5..8111495737 100644 --- a/web/src/components/PluginFlow/components/FlowGraph/index.ts +++ b/web/src/components/PluginFlow/components/FlowGraph/index.ts @@ -14,4 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { default } from './FlowGraph' +export { default } from './FlowGraph'; diff --git a/web/src/components/PluginFlow/components/FlowGraph/shapes.ts b/web/src/components/PluginFlow/components/FlowGraph/shapes.ts index 2e9756ea60..42d9721f70 100644 --- a/web/src/components/PluginFlow/components/FlowGraph/shapes.ts +++ b/web/src/components/PluginFlow/components/FlowGraph/shapes.ts @@ -14,12 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Graph } from '@antv/x6' +import { Graph } from '@antv/x6'; import defaultPluginImg from '../../../../../public/static/default-plugin.png'; import { DEFAULT_SHAPE_RECT_OPINIONS, FlowGraphShape } from '../../constants'; -export const FlowChartRect = Graph.registerNode(FlowGraphShape.base, DEFAULT_SHAPE_RECT_OPINIONS) +export const FlowChartRect = Graph.registerNode(FlowGraphShape.base, DEFAULT_SHAPE_RECT_OPINIONS); export const FlowChartConditionRect = Graph.registerNode(FlowGraphShape.condition, { ...DEFAULT_SHAPE_RECT_OPINIONS, @@ -36,8 +36,8 @@ export const FlowChartConditionRect = Graph.registerNode(FlowGraphShape.conditio group: 'bottom', }, ], - } -}) + }, +}); export const FlowChartStartRect = Graph.registerNode(FlowGraphShape.start, { ...DEFAULT_SHAPE_RECT_OPINIONS, @@ -48,8 +48,8 @@ export const FlowChartStartRect = Graph.registerNode(FlowGraphShape.start, { group: 'bottom', }, ], - } -}) + }, +}); export const FlowChartEndRect = Graph.registerNode(FlowGraphShape.end, { ...DEFAULT_SHAPE_RECT_OPINIONS, @@ -60,8 +60,8 @@ export const FlowChartEndRect = Graph.registerNode(FlowGraphShape.end, { group: 'top', }, ], - } -}) + }, +}); export const FlowChartPluginRect = Graph.registerNode(FlowGraphShape.plugin, { inherit: 'rect', @@ -74,8 +74,7 @@ export const FlowChartPluginRect = Graph.registerNode(FlowGraphShape.plugin, { fill: 'rgba(95,149,255,0.05)', }, image: { - 'xlink:href': - defaultPluginImg, + 'xlink:href': defaultPluginImg, width: 16, height: 16, x: 12, @@ -155,7 +154,7 @@ export const FlowChartPluginRect = Graph.registerNode(FlowGraphShape.plugin, { }, { group: 'bottom', - } + }, ], }, -}) +}); diff --git a/web/src/components/PluginFlow/components/Toolbar/index.tsx b/web/src/components/PluginFlow/components/Toolbar/index.tsx index 7931a26223..8cb2cf348e 100644 --- a/web/src/components/PluginFlow/components/Toolbar/index.tsx +++ b/web/src/components/PluginFlow/components/Toolbar/index.tsx @@ -21,10 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -import React, { useEffect, useState } from 'react' -import { Toolbar } from '@antv/x6-react-components' -import FlowGraph from '../FlowGraph' -import { DataUri } from '@antv/x6' +import React, { useEffect, useState } from 'react'; +import { Toolbar } from '@antv/x6-react-components'; +import FlowGraph from '../FlowGraph'; +import { DataUri } from '@antv/x6'; import { ClearOutlined, SaveOutlined, @@ -34,127 +34,123 @@ import { CopyOutlined, ScissorOutlined, SnippetsOutlined, -} from '@ant-design/icons' -import '@antv/x6-react-components/es/toolbar/style/index.css' +} from '@ant-design/icons'; +import '@antv/x6-react-components/es/toolbar/style/index.css'; -const { Item, Group } = Toolbar +const { Item, Group } = Toolbar; const ToolbarComponent = () => { - const [canUndo, setCanUndo] = useState(false) - const [canRedo, setCanRedo] = useState(false) + const [canUndo, setCanUndo] = useState(false); + const [canRedo, setCanRedo] = useState(false); const copy = () => { - const { graph } = FlowGraph - const cells = graph.getSelectedCells() + const { graph } = FlowGraph; + const cells = graph.getSelectedCells(); if (cells.length) { - graph.copy(cells) + graph.copy(cells); } - return false - } + return false; + }; const cut = () => { - const { graph } = FlowGraph - const cells = graph.getSelectedCells() + const { graph } = FlowGraph; + const cells = graph.getSelectedCells(); if (cells.length) { - graph.cut(cells) + graph.cut(cells); } - return false - } + return false; + }; const paste = () => { - const { graph } = FlowGraph + const { graph } = FlowGraph; if (!graph.isClipboardEmpty()) { - const cells = graph.paste({ offset: 32 }) - graph.cleanSelection() - graph.select(cells) + const cells = graph.paste({ offset: 32 }); + graph.cleanSelection(); + graph.select(cells); } - return false - } + return false; + }; useEffect(() => { - const { graph } = FlowGraph - const { history } = graph - setCanUndo(history.canUndo()) - setCanRedo(history.canRedo()) + const { graph } = FlowGraph; + const { history } = graph; + setCanUndo(history.canUndo()); + setCanRedo(history.canRedo()); history.on('change', () => { - setCanUndo(history.canUndo()) - setCanRedo(history.canRedo()) - }) + setCanUndo(history.canUndo()); + setCanRedo(history.canRedo()); + }); graph.bindKey(['meta+z', 'ctrl+z'], () => { if (history.canUndo()) { - history.undo() + history.undo(); } - return false - }) + return false; + }); graph.bindKey(['meta+shift+z', 'ctrl+y'], () => { if (history.canRedo()) { - history.redo() + history.redo(); } - return false - }) + return false; + }); graph.bindKey(['meta+d', 'ctrl+d'], () => { - graph.clearCells() - return false - }) + graph.clearCells(); + return false; + }); graph.bindKey(['meta+s', 'ctrl+s'], () => { graph.toPNG((datauri: string) => { - DataUri.downloadDataUri(datauri, 'chart.png') - }) - return false - }) + DataUri.downloadDataUri(datauri, 'chart.png'); + }); + return false; + }); graph.bindKey(['meta+p', 'ctrl+p'], () => { - graph.printPreview() - return false - }) - graph.bindKey(['meta+c', 'ctrl+c'], copy) - graph.bindKey(['meta+v', 'ctrl+v'], paste) - graph.bindKey(['meta+x', 'ctrl+x'], cut) - }, []) + graph.printPreview(); + return false; + }); + graph.bindKey(['meta+c', 'ctrl+c'], copy); + graph.bindKey(['meta+v', 'ctrl+v'], paste); + graph.bindKey(['meta+x', 'ctrl+x'], cut); + }, []); const handleClick = (name: string) => { - const { graph } = FlowGraph + const { graph } = FlowGraph; switch (name) { case 'undo': - graph.history.undo() - break + graph.history.undo(); + break; case 'redo': - graph.history.redo() - break + graph.history.redo(); + break; case 'delete': - graph.clearCells() - break + graph.clearCells(); + break; case 'save': graph.toPNG((datauri: string) => { - DataUri.downloadDataUri(datauri, 'chart.png') - }) - break + DataUri.downloadDataUri(datauri, 'chart.png'); + }); + break; case 'print': - graph.printPreview() - break + graph.printPreview(); + break; case 'copy': - copy() - break + copy(); + break; case 'cut': - cut() - break + cut(); + break; case 'paste': - paste() - break + paste(); + break; default: - break + break; } - } + }; return (
- } - tooltip="Clear (Cmd + D, Ctrl + D)" - /> + } tooltip="Clear (Cmd + D, Ctrl + D)" /> { } /> } /> - } - /> + } /> } tooltip="Save (Cmd + S, Ctrl + S)" /> - } - tooltip="Print (Cmd + P, Ctrl + P)" - /> + } tooltip="Print (Cmd + P, Ctrl + P)" />
- ) -} + ); +}; -export default ToolbarComponent +export default ToolbarComponent; diff --git a/web/src/components/PluginFlow/constants.ts b/web/src/components/PluginFlow/constants.ts index 88212ca0e3..f1d3987a3b 100644 --- a/web/src/components/PluginFlow/constants.ts +++ b/web/src/components/PluginFlow/constants.ts @@ -14,13 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Shape, Dom } from '@antv/x6' -import type { Addon, Graph, Cell } from '@antv/x6' -import { formatMessage } from 'umi' +import { Shape, Dom } from '@antv/x6'; +import type { Addon, Graph, Cell } from '@antv/x6'; +import { formatMessage } from 'umi'; -export const DEFAULT_STENCIL_WIDTH = 280 -export const DEFAULT_TOOLBAR_HEIGHT = 38 -export const DEFAULT_SHAPE_TEXT_EDIT_CLASS_NAME = ".flow-graph-shape-text-editor" +export const DEFAULT_STENCIL_WIDTH = 280; +export const DEFAULT_TOOLBAR_HEIGHT = 38; +export const DEFAULT_SHAPE_TEXT_EDIT_CLASS_NAME = '.flow-graph-shape-text-editor'; export const DEFAULT_OPINIONS: Partial = { scroller: true, @@ -58,24 +58,19 @@ export const DEFAULT_OPINIONS: Partial = { name: 'manhattan', }, zIndex: 0, - }) + }); }, - validateConnection({ - sourceView, - targetView, - sourceMagnet, - targetMagnet, - }) { + validateConnection({ sourceView, targetView, sourceMagnet, targetMagnet }) { if (sourceView === targetView) { - return false + return false; } if (!sourceMagnet) { - return false + return false; } if (!targetMagnet) { - return false + return false; } - return true + return true; }, }, highlighting: { @@ -101,32 +96,32 @@ export const DEFAULT_OPINIONS: Partial = { embedding: { enabled: true, findParent({ node }) { - const bbox = node.getBBox() + const bbox = node.getBBox(); return this.getNodes().filter((item) => { - const data = item.getData() + const data = item.getData(); if (data && data.parent) { - const targetBBox = item.getBBox() - return bbox.isIntersectWithRect(targetBBox) + const targetBBox = item.getBBox(); + return bbox.isIntersectWithRect(targetBBox); } - return false - }) + return false; + }); }, }, -} +}; export const DEFAULT_STENCIL_OPINIONS: Partial = { title: formatMessage({ id: 'component.plugin-flow.text.nodes-area' }), stencilGraphWidth: DEFAULT_STENCIL_WIDTH, search: (cell, keyword) => { if (keyword) { - return (cell as any).label?.indexOf(keyword) !== -1 + return (cell as any).label?.indexOf(keyword) !== -1; } - return true + return true; }, notFoundText: formatMessage({ id: 'component.plugin-flow.text.nodes.not-found' }), placeholder: formatMessage({ id: 'component.plugin-flow.text.search-nodes.placeholder' }), collapsable: true, -} +}; export const DEFAULT_SHAPE_RECT_OPINIONS = { inherit: 'rect', @@ -169,7 +164,7 @@ export const DEFAULT_SHAPE_RECT_OPINIONS = { { tagName: 'text', selector: 'text', - } + }, ], ports: { groups: { @@ -249,14 +244,14 @@ export const DEFAULT_SHAPE_RECT_OPINIONS = { }, ], }, -} +}; export enum FlowGraphShape { base = 'flow-chart-rect', condition = 'flow-chart-condition-rect', start = 'flow-chart-start-rect', end = 'flow-chart-end-rect', - plugin = 'flow-chart-plugin-rect' + plugin = 'flow-chart-plugin-rect', } export enum FlowGraphEvent { @@ -268,14 +263,14 @@ export const DEFAULT_PLUGIN_PROPS = { id: '', name: '', visible: false, - data: {} -} + data: {}, +}; export const DEFAULT_CONDITION_PROPS = { visible: false, id: '', - data: '' -} + data: '', +}; export const DEFAULT_PLUGIN_FLOW_DATA: { chart: { @@ -285,10 +280,10 @@ export const DEFAULT_PLUGIN_FLOW_DATA: { rule: Record; } = { chart: { - cells: [] + cells: [], }, conf: {}, rule: { - root: "" - } -} + root: '', + }, +}; diff --git a/web/src/components/PluginFlow/index.ts b/web/src/components/PluginFlow/index.ts index fd368ef213..eb201067a9 100644 --- a/web/src/components/PluginFlow/index.ts +++ b/web/src/components/PluginFlow/index.ts @@ -14,4 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { default } from './PluginFlow' +export { default } from './PluginFlow'; diff --git a/web/src/components/PluginFlow/locales/en-US.ts b/web/src/components/PluginFlow/locales/en-US.ts index fdec09a1bc..4e5c8f215c 100644 --- a/web/src/components/PluginFlow/locales/en-US.ts +++ b/web/src/components/PluginFlow/locales/en-US.ts @@ -28,14 +28,18 @@ export default { 'component.plugin-flow.text.nodes-area': 'Available Nodes', 'component.plugin-flow.text.nodes.not-found': 'Not Found', 'component.plugin-flow.text.search-nodes.placeholder': 'Search plugin by name', - 'component.plugin-flow.text.condition-rule.tooltip': 'The judgment condition of the node. e.g: code == 503', + 'component.plugin-flow.text.condition-rule.tooltip': + 'The judgment condition of the node. e.g: code == 503', 'component.plugin-flow.text.line': 'Line', 'component.plugin-flow.text.grid': 'Grid', 'component.plugin-flow.text.background': 'Background', 'component.plugin-flow.text.node': 'Node', 'component.plugin-flow.text.text': 'Text', - 'component.plugin-flow.text.condition-without-configuration': 'Please check all condition nodes\' data', - 'component.plugin-flow.text.preview.readonly': 'NOTE: your actions on the following drawer will not be preserved.', - 'component.plugin-flow.text.both-modes-exist': 'The orchestration mode configuration will override the normal mode configuration, are you sure to continue?', - 'component.plugin-flow.text.both-modes-exist.title': 'Attention' -} + 'component.plugin-flow.text.condition-without-configuration': + "Please check all condition nodes' data", + 'component.plugin-flow.text.preview.readonly': + 'NOTE: your actions on the following drawer will not be preserved.', + 'component.plugin-flow.text.both-modes-exist': + 'The orchestration mode configuration will override the normal mode configuration, are you sure to continue?', + 'component.plugin-flow.text.both-modes-exist.title': 'Attention', +}; diff --git a/web/src/components/PluginFlow/locales/zh-CN.ts b/web/src/components/PluginFlow/locales/zh-CN.ts index 4486dff121..e3b3746a4f 100644 --- a/web/src/components/PluginFlow/locales/zh-CN.ts +++ b/web/src/components/PluginFlow/locales/zh-CN.ts @@ -37,5 +37,5 @@ export default { 'component.plugin-flow.text.condition-without-configuration': '请检查条件判断元件的配置', 'component.plugin-flow.text.preview.readonly': '请注意:在当前页面,您在画布上地操作不会被保留。', 'component.plugin-flow.text.both-modes-exist': '编排模式配置将覆盖普通模式配置,是否继续操作?', - 'component.plugin-flow.text.both-modes-exist.title': '配置冲突' -} + 'component.plugin-flow.text.both-modes-exist.title': '配置冲突', +}; diff --git a/web/src/components/RawDataEditor/RawDataEditor.tsx b/web/src/components/RawDataEditor/RawDataEditor.tsx index bf8a24d946..7d13510ace 100644 --- a/web/src/components/RawDataEditor/RawDataEditor.tsx +++ b/web/src/components/RawDataEditor/RawDataEditor.tsx @@ -20,17 +20,17 @@ import { LinkOutlined } from '@ant-design/icons'; import { CopyToClipboard } from 'react-copy-to-clipboard'; import { useIntl } from 'umi'; import { js_beautify } from 'js-beautify'; -import type {Monaco} from "@monaco-editor/react"; -import Editor from "@monaco-editor/react"; -import type {languages} from "monaco-editor"; +import type { Monaco } from '@monaco-editor/react'; +import Editor from '@monaco-editor/react'; +import type { languages } from 'monaco-editor'; import { json2yaml, yaml2json } from '../../helpers'; type Props = { - visible: boolean, - readonly: boolean, - type: 'route' | 'service' | 'consumer' | 'upstream' - data: Record, + visible: boolean; + readonly: boolean; + type: 'route' | 'service' | 'consumer' | 'upstream'; + data: Record; onClose?: () => void; onSubmit?: (data: Record) => void; }; @@ -40,12 +40,19 @@ enum monacoLanguageList { YAML = 'YAML', } -const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = {}, onClose = () => { }, onSubmit = () => { } }) => { +const RawDataEditor: React.FC = ({ + visible, + readonly = true, + type, + data = {}, + onClose = () => {}, + onSubmit = () => {}, +}) => { const { formatMessage } = useIntl(); const [monacoLanguage, setMonacoLanguage] = useState( monacoLanguageList.JSON, ); - const [content, setContent] = useState('') + const [content, setContent] = useState(''); useEffect(() => { switch (monacoLanguage) { @@ -53,17 +60,17 @@ const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = setContent(JSON.stringify(data, null, 2)); break; case monacoLanguageList.YAML: { - const {data: yamlData} = json2yaml(JSON.stringify(data, null, 2)); - setContent(yamlData) + const { data: yamlData } = json2yaml(JSON.stringify(data, null, 2)); + setContent(yamlData); break; } default: } - }, [data]) + }, [data]); useEffect(() => { setMonacoLanguage(monacoLanguageList.JSON); - }, [visible]) + }, [visible]); const modeOptions = [ { label: monacoLanguageList.JSON, value: monacoLanguageList.JSON }, @@ -73,20 +80,20 @@ const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = const handleModeChange = (value: PluginComponent.MonacoLanguage) => { switch (value) { case monacoLanguageList.JSON: - setContent(c => { - const {data:jsonData,error} = yaml2json(c, true); - if (error){ - notification.error({message: formatMessage({ id: 'component.global.invalidYaml' })}); + setContent((c) => { + const { data: jsonData, error } = yaml2json(c, true); + if (error) { + notification.error({ message: formatMessage({ id: 'component.global.invalidYaml' }) }); return c; } - return js_beautify(jsonData, {indent_size: 2}); + return js_beautify(jsonData, { indent_size: 2 }); }); break; case monacoLanguageList.YAML: - setContent(c => { - const {data:yamlData,error} = json2yaml(c); - if (error){ - notification.error({message: formatMessage({ id: 'component.global.invalidJson' })}); + setContent((c) => { + const { data: yamlData, error } = json2yaml(c); + if (error) { + notification.error({ message: formatMessage({ id: 'component.global.invalidJson' }) }); return c; } return yamlData; @@ -95,32 +102,34 @@ const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = default: break; } - setMonacoLanguage(value) + setMonacoLanguage(value); }; - const formatYaml = (yaml: string): string=> { - const json=yaml2json(yaml,true) - if (json.error){ + const formatYaml = (yaml: string): string => { + const json = yaml2json(yaml, true); + if (json.error) { return yaml; } return json2yaml(json.data).data; - } + }; const editorWillMount = (monaco: Monaco) => { const yamlFormatProvider: languages.DocumentFormattingEditProvider = { provideDocumentFormattingEdits(model) { - return [{ - text: formatYaml(model.getValue()), - range: model.getFullModelRange() - }]; - } + return [ + { + text: formatYaml(model.getValue()), + range: model.getFullModelRange(), + }, + ]; + }, }; - monaco.languages.registerDocumentFormattingEditProvider("yaml",yamlFormatProvider); + monaco.languages.registerDocumentFormattingEditProvider('yaml', yamlFormatProvider); monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, - trailingCommas: "error", + trailingCommas: 'error', }); - } + }; return ( <> @@ -147,7 +156,9 @@ const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = : yaml2json(content, false).data; onSubmit(editorData); } catch (error) { - notification.error({message: formatMessage({ id: 'component.global.invalidJson' })}); + notification.error({ + message: formatMessage({ id: 'component.global.invalidJson' }), + }); } }} > @@ -167,19 +178,22 @@ const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = onChange={(value: PluginComponent.MonacoLanguage) => { handleModeChange(value); }} - data-cy='monaco-language' + data-cy="monaco-language" />, - { - if (!result) { - notification.error({ - message: formatMessage({ id: 'component.global.copyFail' }), + { + if (!result) { + notification.error({ + message: formatMessage({ id: 'component.global.copyFail' }), + }); + return; + } + notification.success({ + message: formatMessage({ id: 'component.global.copySuccess' }), }); - return; - } - notification.success({ - message: formatMessage({ id: 'component.global.copySuccess' }), - }); - }}> + }} + > @@ -188,9 +202,7 @@ const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = type="default" icon={} onClick={() => { - window.open( - `https://apisix.apache.org/docs/apisix/admin-api#${type}`, - ); + window.open(`https://apisix.apache.org/docs/apisix/admin-api#${type}`); }} key={1} > @@ -200,14 +212,14 @@ const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = /> { - if (text){ + onChange={(text) => { + if (text) { setContent(text); } else { setContent(''); } }} - onMount={(editor)=>{ + onMount={(editor) => { // NOTE: for debug & test // @ts-ignore window.monacoEditor = editor; @@ -215,12 +227,12 @@ const RawDataEditor: React.FC = ({ visible, readonly = true, type, data = beforeMount={editorWillMount} language={monacoLanguage.toLocaleLowerCase()} options={{ - scrollbar:{ + scrollbar: { vertical: 'hidden', horizontal: 'hidden', }, - wordWrap: "on", - minimap: {enabled: false}, + wordWrap: 'on', + minimap: { enabled: false }, readOnly: readonly, }} /> diff --git a/web/src/components/Upstream/UpstreamForm.tsx b/web/src/components/Upstream/UpstreamForm.tsx index 8f07e6e3ec..2a7cb84f2e 100644 --- a/web/src/components/Upstream/UpstreamForm.tsx +++ b/web/src/components/Upstream/UpstreamForm.tsx @@ -21,8 +21,8 @@ import type { FormInstance } from 'antd/es/form'; import PanelSection from '@/components/PanelSection'; import PassiveCheck from './components/passive-check'; -import ActiveCheck from './components/active-check' -import Nodes from './components/Nodes' +import ActiveCheck from './components/active-check'; +import Nodes from './components/Nodes'; import Scheme from './components/Scheme'; import Timeout from './components/Timeout'; import Type from './components/Type'; @@ -45,16 +45,26 @@ type Props = { // FIXME: use proper typing ref?: any; required?: boolean; - neverReadonly?: boolean + neverReadonly?: boolean; }; /** * UpstreamForm is used to reuse Upstream Form UI, * before using this component, we need to execute the following command: * form.setFieldsValue(convertToFormData(VALUE_FROM_API)) -*/ + */ const UpstreamForm: React.FC = forwardRef( - ({ form, disabled = false, list = [], showSelector = false, required = true, neverReadonly = false }, ref) => { + ( + { + form, + disabled = false, + list = [], + showSelector = false, + required = true, + neverReadonly = false, + }, + ref, + ) => { const { formatMessage } = useIntl(); const [readonly, setReadonly] = useState(false); const [hiddenForm, setHiddenForm] = useState(false); @@ -63,17 +73,17 @@ const UpstreamForm: React.FC = forwardRef( { label: formatMessage({ id: 'page.upstream.step.connect.timeout' }), name: ['timeout', 'connect'], - desc: formatMessage({ id: 'page.upstream.step.connect.timeout.desc' }) + desc: formatMessage({ id: 'page.upstream.step.connect.timeout.desc' }), }, { label: formatMessage({ id: 'page.upstream.step.send.timeout' }), name: ['timeout', 'send'], - desc: formatMessage({ id: 'page.upstream.step.send.timeout.desc' }) + desc: formatMessage({ id: 'page.upstream.step.send.timeout.desc' }), }, { label: formatMessage({ id: 'page.upstream.step.read.timeout' }), name: ['timeout', 'read'], - desc: formatMessage({ id: 'page.upstream.step.read.timeout.desc' }) + desc: formatMessage({ id: 'page.upstream.step.read.timeout.desc' }), }, ]; @@ -84,64 +94,69 @@ const UpstreamForm: React.FC = forwardRef( const resetForm = (upstream_id: string) => { if (upstream_id === undefined) { setReadonly(disabled); - return + return; } if (!neverReadonly) { - setReadonly(!["Custom", "None"].includes(upstream_id) || disabled); + setReadonly(!['Custom', 'None'].includes(upstream_id) || disabled); } /** * upstream_id === None <==> required === false * No need to bind Upstream object. * When creating Route and binds with a Service, no need to configure Upstream in Route. - */ + */ if (upstream_id === 'None') { setHiddenForm(true); - form.resetFields() - form.setFieldsValue({ upstream_id: 'None' }) - return + form.resetFields(); + form.setFieldsValue({ upstream_id: 'None' }); + return; } - setHiddenForm(false) + setHiddenForm(false); // NOTE: Use Ant Design's form object to set data automatically - if (upstream_id === "Custom") { - return + if (upstream_id === 'Custom') { + return; } // NOTE: Set data from Upstream List (Upstream Selector) if (list.length === 0) { - return + return; } - form.resetFields() - const targetData = list.find((item) => item.id === upstream_id) as UpstreamComponent.ResponseData + form.resetFields(); + const targetData = list.find( + (item) => item.id === upstream_id, + ) as UpstreamComponent.ResponseData; if (targetData) { form.setFieldsValue(targetData); } - } + }; /** * upstream_id * - None: No need to bind Upstream to a resource (e.g Service). * - Custom: Users could input values on UpstreamForm * - Upstream ID from API - */ + */ useEffect(() => { const upstream_id = form.getFieldValue('upstream_id'); - resetForm(upstream_id) + resetForm(upstream_id); }, [form.getFieldValue('upstream_id'), list]); const ActiveHealthCheck = () => ( - prev.checks.active.type !== next.checks.active.type}> + prev.checks.active.type !== next.checks.active.type} + > {() => { - const type = form.getFieldValue(['checks', 'active', 'type']) + const type = form.getFieldValue(['checks', 'active', 'type']); if (['https'].includes(type)) { - return + return ; } - return null + return null; }} @@ -198,58 +213,65 @@ const UpstreamForm: React.FC = forwardRef( - + - { - () => { - const active = form.getFieldValue(['custom', 'checks', 'active']) - if (active) { - return ( - - ) - } - return null + {() => { + const active = form.getFieldValue(['custom', 'checks', 'active']); + if (active) { + return ; } - } + return null; + }} - + - prev.custom?.checks?.passive !== next.custom?.checks?.passive} noStyle> - { - () => { - const passive = form.getFieldValue(['custom', 'checks', 'passive']) - const active = form.getFieldValue(['custom', 'checks', 'active']) - if (passive) { - /* - * When enable passive check, we should enable active check, too. - * When we use form.setFieldsValue to enable active check, error throws. - * We choose to alert users first, and need users to enable active check manually. - */ - if (!active) { - notification.warn({ - message: formatMessage({ id: 'component.upstream.other.health-check.invalid' }), - description: formatMessage({ id: 'component.upstream.other.health-check.passive-only' }) - }) - } - return + + prev.custom?.checks?.passive !== next.custom?.checks?.passive + } + noStyle + > + {() => { + const passive = form.getFieldValue(['custom', 'checks', 'passive']); + const active = form.getFieldValue(['custom', 'checks', 'active']); + if (passive) { + /* + * When enable passive check, we should enable active check, too. + * When we use form.setFieldsValue to enable active check, error throws. + * We choose to alert users first, and need users to enable active check manually. + */ + if (!active) { + notification.warn({ + message: formatMessage({ id: 'component.upstream.other.health-check.invalid' }), + description: formatMessage({ + id: 'component.upstream.other.health-check.passive-only', + }), + }); } - return null + return ; } - } + return null; + }} - ) - } + ); + }; return ( -
+ {showSelector && ( = forwardRef( prev.scheme !== next.scheme}> - { - () => { - const scheme = form.getFieldValue("scheme") as string - if (["https", "grpcs"].includes(scheme)) { - return - } - return null + {() => { + const scheme = form.getFieldValue('scheme') as string; + if (['https', 'grpcs'].includes(scheme)) { + return ; } - } + return null; + }} {timeoutFields.map((item, index) => ( diff --git a/web/src/components/Upstream/components/DiscoveryType.tsx b/web/src/components/Upstream/components/DiscoveryType.tsx index 031de335af..40d512feb3 100644 --- a/web/src/components/Upstream/components/DiscoveryType.tsx +++ b/web/src/components/Upstream/components/DiscoveryType.tsx @@ -14,21 +14,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Input } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Input } from 'antd'; +import { useIntl } from 'umi'; type Props = { readonly?: boolean; -} +}; const DiscoveryType: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - - + + - ) -} + ); +}; -export default DiscoveryType +export default DiscoveryType; diff --git a/web/src/components/Upstream/components/Nodes.tsx b/web/src/components/Upstream/components/Nodes.tsx index 4b95c5a5d5..c4a8ff778b 100644 --- a/web/src/components/Upstream/components/Nodes.tsx +++ b/web/src/components/Upstream/components/Nodes.tsx @@ -14,30 +14,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Input, Row, Col, InputNumber, Button } from 'antd' -import { useIntl } from 'umi' -import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons' +import React from 'react'; +import { Form, Input, Row, Col, InputNumber, Button } from 'antd'; +import { useIntl } from 'umi'; +import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; -import { removeBtnStyle } from '..' +import { removeBtnStyle } from '..'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - + {(fields, { add, remove }) => ( <> - + {fields.map((field, index) => ( = ({ readonly }) => { }), }, { - pattern: new RegExp( - /^\*?[0-9a-zA-Z-._]+$/, - 'g', - ), + pattern: new RegExp(/^\*?[0-9a-zA-Z-._]+$/, 'g'), message: formatMessage({ id: 'page.route.form.itemRulesPatternMessage.domain', - }) + }), }, ]} > @@ -107,7 +110,10 @@ const Component: React.FC = ({ readonly }) => { {!readonly && ( - remove(field.name)} /> + remove(field.name)} + /> )} @@ -124,7 +130,7 @@ const Component: React.FC = ({ readonly }) => { )} - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/PassHost.tsx b/web/src/components/Upstream/components/PassHost.tsx index 72b582120b..3a09262328 100644 --- a/web/src/components/Upstream/components/PassHost.tsx +++ b/web/src/components/Upstream/components/PassHost.tsx @@ -14,32 +14,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Input, notification, Select } from 'antd' -import { useIntl } from 'umi' -import type { FormInstance } from 'antd/lib/form' +import React from 'react'; +import { Form, Input, notification, Select } from 'antd'; +import { useIntl } from 'umi'; +import type { FormInstance } from 'antd/lib/form'; type Props = { - form: FormInstance - readonly?: boolean -} + form: FormInstance; + readonly?: boolean; +}; const Component: React.FC = ({ form, readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); const options = [ { - value: "pass", - label: formatMessage({ id: 'page.upstream.step.pass-host.pass' }) - }, { - value: "node", - label: formatMessage({ id: 'page.upstream.step.pass-host.node' }) - }, { - value: "rewrite", + value: 'pass', + label: formatMessage({ id: 'page.upstream.step.pass-host.pass' }), + }, + { + value: 'node', + label: formatMessage({ id: 'page.upstream.step.pass-host.node' }), + }, + { + value: 'rewrite', label: formatMessage({ id: 'page.upstream.step.pass-host.rewrite' }), - disabled: true - } - ] + disabled: true, + }, + ]; return ( @@ -49,7 +51,7 @@ const Component: React.FC = ({ form, readonly }) => { initialValue="pass" > + ); } - if (form.getFieldValue('pass_host') === 'node' && (form.getFieldValue('nodes') || []).length !== 1) { + if ( + form.getFieldValue('pass_host') === 'node' && + (form.getFieldValue('nodes') || []).length !== 1 + ) { notification.warning({ - message: formatMessage({id: 'component.upstream.other.pass_host-with-multiple-nodes.title'}), - description: formatMessage({id: 'component.upstream.other.pass_host-with-multiple-nodes'}) - }) - form.setFieldsValue({pass_host: 'pass'}) + message: formatMessage({ + id: 'component.upstream.other.pass_host-with-multiple-nodes.title', + }), + description: formatMessage({ + id: 'component.upstream.other.pass_host-with-multiple-nodes', + }), + }); + form.setFieldsValue({ pass_host: 'pass' }); } return null; }} - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/Retries.tsx b/web/src/components/Upstream/components/Retries.tsx index 51d346e7a6..7baf7b43aa 100644 --- a/web/src/components/Upstream/components/Retries.tsx +++ b/web/src/components/Upstream/components/Retries.tsx @@ -14,27 +14,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - + - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/Scheme.tsx b/web/src/components/Upstream/components/Scheme.tsx index c289e28101..c173c26d2d 100644 --- a/web/src/components/Upstream/components/Scheme.tsx +++ b/web/src/components/Upstream/components/Scheme.tsx @@ -14,32 +14,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Select } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Select } from 'antd'; +import { useIntl } from 'umi'; const options = [ { - label: "HTTP", - value: "http" - }, { - label: "HTTPs", - value: "https" - }, { - label: "gRPC", - value: "grpc" - }, { - label: "gRPCs", - value: "grpcs" - } -] + label: 'HTTP', + value: 'http', + }, + { + label: 'HTTPs', + value: 'https', + }, + { + label: 'gRPC', + value: 'grpc', + }, + { + label: 'gRPCs', + value: 'grpcs', + }, +]; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Scheme: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ readonly }) => { initialValue="http" > - ) -} + ); +}; -export default Scheme +export default Scheme; diff --git a/web/src/components/Upstream/components/ServiceName.tsx b/web/src/components/Upstream/components/ServiceName.tsx index b0ef62cc3f..18055ebeff 100644 --- a/web/src/components/Upstream/components/ServiceName.tsx +++ b/web/src/components/Upstream/components/ServiceName.tsx @@ -14,21 +14,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Input } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Input } from 'antd'; +import { useIntl } from 'umi'; type Props = { readonly?: boolean; -} +}; const ServiceName: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - - + + - ) -} + ); +}; -export default ServiceName +export default ServiceName; diff --git a/web/src/components/Upstream/components/TLS.tsx b/web/src/components/Upstream/components/TLS.tsx index bdc01030d7..b2472714df 100644 --- a/web/src/components/Upstream/components/TLS.tsx +++ b/web/src/components/Upstream/components/TLS.tsx @@ -14,17 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Row, Col, Select, FormInstance, Input } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Row, Col, Select, FormInstance, Input } from 'antd'; +import { useIntl } from 'umi'; type Props = { form: FormInstance; readonly?: boolean; -} +}; const TLSComponent: React.FC = ({ form, readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( @@ -35,18 +35,13 @@ const TLSComponent: React.FC = ({ form, readonly }) => { > - + @@ -55,39 +50,53 @@ const TLSComponent: React.FC = ({ form, readonly }) => { { - return prev.custom.tls !== next.custom.tls + return prev.custom.tls !== next.custom.tls; }} > - { - () => { - if (form.getFieldValue(["custom", "tls"]) === 'enable') { - return ( - - - - - - - - - ) - } - return null + {() => { + if (form.getFieldValue(['custom', 'tls']) === 'enable') { + return ( + + + + + + + + + ); } - } + return null; + }} - ) -} + ); +}; -export default TLSComponent +export default TLSComponent; diff --git a/web/src/components/Upstream/components/TimeUnit.tsx b/web/src/components/Upstream/components/TimeUnit.tsx index 292c0cfe7a..67642a1117 100644 --- a/web/src/components/Upstream/components/TimeUnit.tsx +++ b/web/src/components/Upstream/components/TimeUnit.tsx @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' +import React from 'react'; const TimeUnit = () => s; -export default TimeUnit +export default TimeUnit; diff --git a/web/src/components/Upstream/components/Timeout.tsx b/web/src/components/Upstream/components/Timeout.tsx index 8eefdf0118..2063018b99 100644 --- a/web/src/components/Upstream/components/Timeout.tsx +++ b/web/src/components/Upstream/components/Timeout.tsx @@ -14,11 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; -import TimeUnit from './TimeUnit' +import TimeUnit from './TimeUnit'; const Timeout: React.FC<{ label: string; @@ -26,7 +26,7 @@ const Timeout: React.FC<{ name: string[]; readonly?: boolean; }> = ({ label, desc, name, readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - ) -} + ); +}; -export default Timeout +export default Timeout; diff --git a/web/src/components/Upstream/components/Type.tsx b/web/src/components/Upstream/components/Type.tsx index ed656700fc..b72d6cdfb8 100644 --- a/web/src/components/Upstream/components/Type.tsx +++ b/web/src/components/Upstream/components/Type.tsx @@ -14,20 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useState } from 'react' -import { AutoComplete, Form, Select } from 'antd' -import { useIntl } from 'umi' -import type { FormInstance } from 'antd/es/form' +import React, { useState } from 'react'; +import { AutoComplete, Form, Select } from 'antd'; +import { useIntl } from 'umi'; +import type { FormInstance } from 'antd/es/form'; -import { HashOnEnum, CommonHashKeyEnum, AlgorithmEnum } from '../constant' +import { HashOnEnum, CommonHashKeyEnum, AlgorithmEnum } from '../constant'; type Props = { - readonly?: boolean - form: FormInstance -} + readonly?: boolean; + form: FormInstance; +}; const CHash: React.FC> = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); const [keySearchWord, setKeySearchWord] = useState(''); const handleSearch = (search: string) => { @@ -35,7 +35,13 @@ const CHash: React.FC> = ({ readonly }) => { }; return ( - + - + {Object.entries(CommonHashKeyEnum) - .filter((([label, value]) => label.startsWith(keySearchWord) || value.startsWith(keySearchWord))) + .filter( + ([label, value]) => + label.startsWith(keySearchWord) || value.startsWith(keySearchWord), + ) .map(([label, value]) => ( {label} @@ -58,11 +71,11 @@ const CHash: React.FC> = ({ readonly }) => { - ) + ); }; const Component: React.FC = ({ readonly, form }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( @@ -91,7 +104,7 @@ const Component: React.FC = ({ readonly, form }) => { }} - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/UpstreamSelector.tsx b/web/src/components/Upstream/components/UpstreamSelector.tsx index 34f7fec16b..2bfa4c03a9 100644 --- a/web/src/components/Upstream/components/UpstreamSelector.tsx +++ b/web/src/components/Upstream/components/UpstreamSelector.tsx @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Select } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Select } from 'antd'; +import { useIntl } from 'umi'; type Upstream = { name?: string; @@ -27,11 +27,11 @@ type Props = { list?: Upstream[]; disabled?: boolean; required?: boolean; - onChange: (id: string) => void -} + onChange: (id: string) => void; +}; const UpstreamSelector: React.FC = ({ onChange, list = [], disabled, required }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ onChange, list = [], disabled, requ data-cy="upstream_selector" disabled={disabled} onChange={onChange} - filterOption={(input, item) => - item?.children.toLowerCase().includes(input.toLowerCase()) - } + filterOption={(input, item) => item?.children.toLowerCase().includes(input.toLowerCase())} > - {formatMessage({id: 'component.upstream.other.none'})} + + {formatMessage({ id: 'component.upstream.other.none' })} + {[ { name: formatMessage({ id: 'page.upstream.step.select.upstream.select.option' }), @@ -61,7 +61,7 @@ const UpstreamSelector: React.FC = ({ onChange, list = [], disabled, requ ))} - ) -} + ); +}; -export default UpstreamSelector +export default UpstreamSelector; diff --git a/web/src/components/Upstream/components/active-check/Concurrency.tsx b/web/src/components/Upstream/components/active-check/Concurrency.tsx index 8ef19d3d76..4233ee3ee5 100644 --- a/web/src/components/Upstream/components/active-check/Concurrency.tsx +++ b/web/src/components/Upstream/components/active-check/Concurrency.tsx @@ -14,24 +14,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const ConcurrencyComponent: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - + - ) -} + ); +}; -export default ConcurrencyComponent +export default ConcurrencyComponent; diff --git a/web/src/components/Upstream/components/active-check/Healthy/HttpStatuses.tsx b/web/src/components/Upstream/components/active-check/Healthy/HttpStatuses.tsx index 5357ef7f68..0b4d6443e9 100644 --- a/web/src/components/Upstream/components/active-check/Healthy/HttpStatuses.tsx +++ b/web/src/components/Upstream/components/active-check/Healthy/HttpStatuses.tsx @@ -14,19 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Row, Col, Button, InputNumber } from 'antd' -import { useIntl } from 'umi' -import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons' +import React from 'react'; +import { Form, Row, Col, Button, InputNumber } from 'antd'; +import { useIntl } from 'umi'; +import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; -import { removeBtnStyle } from '@/components/Upstream' +import { removeBtnStyle } from '@/components/Upstream'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( @@ -34,9 +34,13 @@ const Component: React.FC = ({ readonly }) => { <> {fields.map((field, index) => ( @@ -70,6 +74,6 @@ const Component: React.FC = ({ readonly }) => { )} - ) -} -export default Component + ); +}; +export default Component; diff --git a/web/src/components/Upstream/components/active-check/Healthy/Interval.tsx b/web/src/components/Upstream/components/active-check/Healthy/Interval.tsx index 0a4e3c8a1a..53240d0bba 100644 --- a/web/src/components/Upstream/components/active-check/Healthy/Interval.tsx +++ b/web/src/components/Upstream/components/active-check/Healthy/Interval.tsx @@ -14,22 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' -import TimeUnit from '../../TimeUnit' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; +import TimeUnit from '../../TimeUnit'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ readonly }) => { - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/active-check/Healthy/Successes.tsx b/web/src/components/Upstream/components/active-check/Healthy/Successes.tsx index a096cdfd27..fe16b0cc4c 100644 --- a/web/src/components/Upstream/components/active-check/Healthy/Successes.tsx +++ b/web/src/components/Upstream/components/active-check/Healthy/Successes.tsx @@ -14,22 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Form, InputNumber } from 'antd' -import React from 'react' -import { useIntl } from 'umi' +import { Form, InputNumber } from 'antd'; +import React from 'react'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ readonly }) => { rules={[ { required: true, - message: formatMessage({ id: 'component.upstream.fields.checks.active.healthy.successes.required' }), + message: formatMessage({ + id: 'component.upstream.fields.checks.active.healthy.successes.required', + }), }, ]} initialValue={2} @@ -45,7 +49,7 @@ const Component: React.FC = ({ readonly }) => { - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/active-check/Healthy/index.ts b/web/src/components/Upstream/components/active-check/Healthy/index.ts index f803f58c61..e6ea2ca680 100644 --- a/web/src/components/Upstream/components/active-check/Healthy/index.ts +++ b/web/src/components/Upstream/components/active-check/Healthy/index.ts @@ -14,12 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import Interval from './Interval' -import Successes from './Successes' -import HttpStatuses from './HttpStatuses' +import Interval from './Interval'; +import Successes from './Successes'; +import HttpStatuses from './HttpStatuses'; export default { Interval, Successes, - HttpStatuses -} + HttpStatuses, +}; diff --git a/web/src/components/Upstream/components/active-check/Host.tsx b/web/src/components/Upstream/components/active-check/Host.tsx index 87e68a3d93..10fe1aca39 100644 --- a/web/src/components/Upstream/components/active-check/Host.tsx +++ b/web/src/components/Upstream/components/active-check/Host.tsx @@ -14,16 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Input } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Input } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ readonly }) => { name={['checks', 'active', 'host']} rules={[ { - pattern: new RegExp( - /^\*?[0-9a-zA-Z-._]+$/, - 'g', - ), + pattern: new RegExp(/^\*?[0-9a-zA-Z-._]+$/, 'g'), message: formatMessage({ id: 'component.upstream.fields.checks.active.host.scope' }), }, ]} @@ -50,7 +47,7 @@ const Component: React.FC = ({ readonly }) => { /> - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/active-check/HttpPath.tsx b/web/src/components/Upstream/components/active-check/HttpPath.tsx index b99457a27d..c62a81a49f 100644 --- a/web/src/components/Upstream/components/active-check/HttpPath.tsx +++ b/web/src/components/Upstream/components/active-check/HttpPath.tsx @@ -14,16 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Input } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Input } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ readonly }) => { id: 'component.upstream.fields.checks.active.http_path.tooltip', })} > - + - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/active-check/HttpsVerifyCertificate.tsx b/web/src/components/Upstream/components/active-check/HttpsVerifyCertificate.tsx index 0d33feff17..f53c5834fe 100644 --- a/web/src/components/Upstream/components/active-check/HttpsVerifyCertificate.tsx +++ b/web/src/components/Upstream/components/active-check/HttpsVerifyCertificate.tsx @@ -14,27 +14,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Switch } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Switch } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const HttpsVerifyCertificateComponent: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - ) -} + ); +}; -export default HttpsVerifyCertificateComponent +export default HttpsVerifyCertificateComponent; diff --git a/web/src/components/Upstream/components/active-check/Port.tsx b/web/src/components/Upstream/components/active-check/Port.tsx index 030a6c7258..a2d3043702 100644 --- a/web/src/components/Upstream/components/active-check/Port.tsx +++ b/web/src/components/Upstream/components/active-check/Port.tsx @@ -14,16 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( @@ -37,7 +37,7 @@ const Component: React.FC = ({ readonly }) => { /> - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/active-check/ReqHeaders.tsx b/web/src/components/Upstream/components/active-check/ReqHeaders.tsx index 9280ed4428..ce0d72e367 100644 --- a/web/src/components/Upstream/components/active-check/ReqHeaders.tsx +++ b/web/src/components/Upstream/components/active-check/ReqHeaders.tsx @@ -14,29 +14,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Row, Col, Input, Button } from 'antd' -import { useIntl } from 'umi' -import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons' +import React from 'react'; +import { Form, Row, Col, Input, Button } from 'antd'; +import { useIntl } from 'umi'; +import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; -import { removeBtnStyle } from '../../constant' +import { removeBtnStyle } from '../../constant'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( {(fields, { add, remove }) => ( <> {fields.map((field, index) => ( @@ -76,7 +76,7 @@ const Component: React.FC = ({ readonly }) => { )} - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/active-check/Timeout.tsx b/web/src/components/Upstream/components/active-check/Timeout.tsx index f2b6bdc813..1289cca06e 100644 --- a/web/src/components/Upstream/components/active-check/Timeout.tsx +++ b/web/src/components/Upstream/components/active-check/Timeout.tsx @@ -14,26 +14,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' -import TimeUnit from '../TimeUnit' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; +import TimeUnit from '../TimeUnit'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const ActiveCheckTimeoutComponent: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - + - ) -} + ); +}; -export default ActiveCheckTimeoutComponent +export default ActiveCheckTimeoutComponent; diff --git a/web/src/components/Upstream/components/active-check/Type.tsx b/web/src/components/Upstream/components/active-check/Type.tsx index 067bf96fa4..cb7ab79f90 100644 --- a/web/src/components/Upstream/components/active-check/Type.tsx +++ b/web/src/components/Upstream/components/active-check/Type.tsx @@ -14,29 +14,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Select, Row, Col } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, Select, Row, Col } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const options = [ { - label: "HTTP", - value: "http" - }, { - label: "HTTPs", - value: "https" - }, { - label: "TCP", - value: "tcp" - } -] + label: 'HTTP', + value: 'http', + }, + { + label: 'HTTPs', + value: 'https', + }, + { + label: 'TCP', + value: 'tcp', + }, +]; const ActiveCheckTypeComponent: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ readonly }) => { > - + - {options.map(item => { + {options.map((item) => { return ( {item.label} @@ -63,7 +62,7 @@ const PassiveCheckTypeComponent: React.FC = ({ readonly }) => { - ) -} + ); +}; -export default PassiveCheckTypeComponent +export default PassiveCheckTypeComponent; diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx b/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx index be282b7312..632bd158e7 100644 --- a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx +++ b/web/src/components/Upstream/components/passive-check/Unhealthy/HttpFailures.tsx @@ -14,22 +14,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ readonly }) => { - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpStatuses.tsx b/web/src/components/Upstream/components/passive-check/Unhealthy/HttpStatuses.tsx index 2127c05728..3b3e37be31 100644 --- a/web/src/components/Upstream/components/passive-check/Unhealthy/HttpStatuses.tsx +++ b/web/src/components/Upstream/components/passive-check/Unhealthy/HttpStatuses.tsx @@ -14,27 +14,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, Row, Col, InputNumber, Button } from 'antd' -import { useIntl } from 'umi' -import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons' +import React from 'react'; +import { Form, Row, Col, InputNumber, Button } from 'antd'; +import { useIntl } from 'umi'; +import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; -import { removeBtnStyle } from '@/components/Upstream/constant' +import { removeBtnStyle } from '@/components/Upstream/constant'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - + {(fields, { add, remove }) => ( <> {fields.map((field, index) => ( @@ -69,7 +74,7 @@ const Component: React.FC = ({ readonly }) => { )} - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/TcpFailures.tsx b/web/src/components/Upstream/components/passive-check/Unhealthy/TcpFailures.tsx index 7828cb2e0b..fec689eb80 100644 --- a/web/src/components/Upstream/components/passive-check/Unhealthy/TcpFailures.tsx +++ b/web/src/components/Upstream/components/passive-check/Unhealthy/TcpFailures.tsx @@ -14,21 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( = ({ readonly }) => { - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/Timeouts.tsx b/web/src/components/Upstream/components/passive-check/Unhealthy/Timeouts.tsx index 6eff53a7e7..aeaacf74b4 100644 --- a/web/src/components/Upstream/components/passive-check/Unhealthy/Timeouts.tsx +++ b/web/src/components/Upstream/components/passive-check/Unhealthy/Timeouts.tsx @@ -14,31 +14,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react' -import { Form, InputNumber } from 'antd' -import { useIntl } from 'umi' +import React from 'react'; +import { Form, InputNumber } from 'antd'; +import { useIntl } from 'umi'; type Props = { - readonly?: boolean -} + readonly?: boolean; +}; const Component: React.FC = ({ readonly }) => { - const { formatMessage } = useIntl() + const { formatMessage } = useIntl(); return ( - + - ) -} + ); +}; -export default Component +export default Component; diff --git a/web/src/components/Upstream/components/passive-check/Unhealthy/index.ts b/web/src/components/Upstream/components/passive-check/Unhealthy/index.ts index 88ab9c2275..e00e5219c2 100644 --- a/web/src/components/Upstream/components/passive-check/Unhealthy/index.ts +++ b/web/src/components/Upstream/components/passive-check/Unhealthy/index.ts @@ -14,14 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import Timeouts from './Timeouts' -import HttpFailures from './HttpFailures' -import TcpFailures from './TcpFailures' -import HttpStatuses from './HttpStatuses' +import Timeouts from './Timeouts'; +import HttpFailures from './HttpFailures'; +import TcpFailures from './TcpFailures'; +import HttpStatuses from './HttpStatuses'; export default { Timeouts, HttpFailures, TcpFailures, - HttpStatuses -} + HttpStatuses, +}; diff --git a/web/src/components/Upstream/components/passive-check/index.ts b/web/src/components/Upstream/components/passive-check/index.ts index f0637fd910..1756651ce5 100644 --- a/web/src/components/Upstream/components/passive-check/index.ts +++ b/web/src/components/Upstream/components/passive-check/index.ts @@ -14,12 +14,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import Healthy from './Healthy' -import Unhealthy from './Unhealthy' -import Type from './Type' +import Healthy from './Healthy'; +import Unhealthy from './Unhealthy'; +import Type from './Type'; export default { Healthy, Unhealthy, - Type -} + Type, +}; diff --git a/web/src/components/Upstream/constant.ts b/web/src/components/Upstream/constant.ts index 66ddc45143..394b53292a 100644 --- a/web/src/components/Upstream/constant.ts +++ b/web/src/components/Upstream/constant.ts @@ -22,10 +22,10 @@ export const removeBtnStyle = { }; export enum AlgorithmEnum { - chash = "chash", - roundrobin = "roundrobin", - ewma = "ewma", - least_conn = "least_conn" + chash = 'chash', + roundrobin = 'roundrobin', + ewma = 'ewma', + least_conn = 'least_conn', } export enum HashOnEnum { @@ -33,7 +33,7 @@ export enum HashOnEnum { header = 'header', cookie = 'cookie', consumer = 'consumer', - vars_combinations = 'vars_combinations' + vars_combinations = 'vars_combinations', } export enum CommonHashKeyEnum { @@ -50,14 +50,14 @@ export enum CommonHashKeyEnum { } export enum SchemeEnum { - grpc = "grpc", - grpcs = "grpcs", - http = "http", - https = "https" + grpc = 'grpc', + grpcs = 'grpcs', + http = 'http', + https = 'https', } export enum PassHostEnum { - pass = "pass", - node = "node", - rewrite = "rewrite" + pass = 'pass', + node = 'node', + rewrite = 'rewrite', } diff --git a/web/src/components/Upstream/locales/en-US.ts b/web/src/components/Upstream/locales/en-US.ts index fca1919a31..6bb9cb6e72 100644 --- a/web/src/components/Upstream/locales/en-US.ts +++ b/web/src/components/Upstream/locales/en-US.ts @@ -38,65 +38,89 @@ export default { 'component.upstream.fields.key.tooltip': 'Key as hashing input', 'component.upstream.fields.retries': 'Retries', - 'component.upstream.fields.retries.tooltip': 'The retry mechanism sends the request to the next upstream node. A value of 0 disables the retry mechanism and leaves the table empty to use the number of available backend nodes.', + 'component.upstream.fields.retries.tooltip': + 'The retry mechanism sends the request to the next upstream node. A value of 0 disables the retry mechanism and leaves the table empty to use the number of available backend nodes.', 'component.upstream.fields.checks.active.type': 'Type', - 'component.upstream.fields.checks.active.type.tooltip': 'Whether to perform active health checks using HTTP or HTTPS, or just attempt a TCP connection.', + 'component.upstream.fields.checks.active.type.tooltip': + 'Whether to perform active health checks using HTTP or HTTPS, or just attempt a TCP connection.', 'component.upstream.fields.checks.active.concurrency': 'Concurrency', - 'component.upstream.fields.checks.active.concurrency.tooltip': 'Number of targets to check concurrently in active health checks.', + 'component.upstream.fields.checks.active.concurrency.tooltip': + 'Number of targets to check concurrently in active health checks.', 'component.upstream.fields.checks.active.host': 'Host', 'component.upstream.fields.checks.active.host.required': 'Please enter the hostname', - 'component.upstream.fields.checks.active.host.tooltip': 'The hostname of the HTTP request used to perform the active health check', + 'component.upstream.fields.checks.active.host.tooltip': + 'The hostname of the HTTP request used to perform the active health check', 'component.upstream.fields.checks.active.host.scope': 'Only letters, numbers and . are supported', 'component.upstream.fields.checks.active.port': 'Port', 'component.upstream.fields.checks.active.http_path': 'HTTP Path', - 'component.upstream.fields.checks.active.http_path.tooltip': 'The path that should be used when issuing the HTTP GET request to the target. The default value is /.', + 'component.upstream.fields.checks.active.http_path.tooltip': + 'The path that should be used when issuing the HTTP GET request to the target. The default value is /.', 'component.upstream.fields.checks.active.https_verify_certificate': 'Verify HTTPs Certificate', - 'component.upstream.fields.checks.active.https_verify_certificate.tooltip': 'Whether to check the validity of the SSL certificate of the remote host when performing active health checks using HTTPS.', + 'component.upstream.fields.checks.active.https_verify_certificate.tooltip': + 'Whether to check the validity of the SSL certificate of the remote host when performing active health checks using HTTPS.', 'component.upstream.fields.checks.active.req_headers': 'Request Headers', - 'component.upstream.fields.checks.active.req_headers.tooltip': 'Additional request headers, example: User-Agent: curl/7.29.0', + 'component.upstream.fields.checks.active.req_headers.tooltip': + 'Additional request headers, example: User-Agent: curl/7.29.0', 'component.upstream.fields.checks.active.healthy.interval': 'Interval', - 'component.upstream.fields.checks.active.healthy.interval.tooltip': 'Interval between checks for healthy targets (in seconds)', + 'component.upstream.fields.checks.active.healthy.interval.tooltip': + 'Interval between checks for healthy targets (in seconds)', 'component.upstream.fields.checks.active.healthy.successes': 'Successes', - 'component.upstream.fields.checks.active.healthy.successes.tooltip': 'Number of successes to consider a target healthy', - 'component.upstream.fields.checks.active.healthy.successes.required': 'Please enter successes number', + 'component.upstream.fields.checks.active.healthy.successes.tooltip': + 'Number of successes to consider a target healthy', + 'component.upstream.fields.checks.active.healthy.successes.required': + 'Please enter successes number', 'component.upstream.fields.checks.active.healthy.http_statuses': 'HTTP Statuses', - 'component.upstream.fields.checks.active.healthy.http_statuses.tooltip': 'An array of HTTP statuses to consider a success, indicating healthiness, when returned by a probe in active health checks.', + 'component.upstream.fields.checks.active.healthy.http_statuses.tooltip': + 'An array of HTTP statuses to consider a success, indicating healthiness, when returned by a probe in active health checks.', 'component.upstream.fields.checks.active.unhealthy.timeouts': 'Timeouts', - 'component.upstream.fields.checks.active.unhealthy.timeouts.tooltip': 'Number of timeouts in active probes to consider a target unhealthy.', + 'component.upstream.fields.checks.active.unhealthy.timeouts.tooltip': + 'Number of timeouts in active probes to consider a target unhealthy.', 'component.upstream.fields.checks.active.unhealthy.http_failures': 'HTTP Failures', - 'component.upstream.fields.checks.active.unhealthy.http_failures.tooltip': 'Number of HTTP failures to consider a target unhealthy', - 'component.upstream.fields.checks.active.unhealthy.http_failures.required': 'Please enter the HTTP failures', + 'component.upstream.fields.checks.active.unhealthy.http_failures.tooltip': + 'Number of HTTP failures to consider a target unhealthy', + 'component.upstream.fields.checks.active.unhealthy.http_failures.required': + 'Please enter the HTTP failures', 'component.upstream.fields.checks.active.unhealthy.tcp_failures': 'TCP Failures', - 'component.upstream.fields.checks.active.unhealthy.tcp_failures.tooltip': 'Number of TCP failures to consider a target unhealthy', - 'component.upstream.fields.checks.active.unhealthy.tcp_failures.required': 'Please enter the TCP Failures', + 'component.upstream.fields.checks.active.unhealthy.tcp_failures.tooltip': + 'Number of TCP failures to consider a target unhealthy', + 'component.upstream.fields.checks.active.unhealthy.tcp_failures.required': + 'Please enter the TCP Failures', 'component.upstream.fields.checks.active.unhealthy.interval': 'Interval', - 'component.upstream.fields.checks.active.unhealthy.interval.tooltip': 'Interval between active health checks for unhealthy targets (in seconds). A value of zero indicates that active probes for healthy targets should not be performed.', - 'component.upstream.fields.checks.active.unhealthy.required': 'Please enter the unhelthy interval', + 'component.upstream.fields.checks.active.unhealthy.interval.tooltip': + 'Interval between active health checks for unhealthy targets (in seconds). A value of zero indicates that active probes for healthy targets should not be performed.', + 'component.upstream.fields.checks.active.unhealthy.required': + 'Please enter the unhelthy interval', 'component.upstream.fields.checks.passive.healthy.successes': 'Successes', - 'component.upstream.fields.checks.passive.healthy.successes.tooltip': 'Number of successes to consider a target healthy', - 'component.upstream.fields.checks.passive.healthy.successes.required': 'Please enter the successes number', + 'component.upstream.fields.checks.passive.healthy.successes.tooltip': + 'Number of successes to consider a target healthy', + 'component.upstream.fields.checks.passive.healthy.successes.required': + 'Please enter the successes number', 'component.upstream.fields.checks.passive.unhealthy.timeouts': 'Timeouts', - 'component.upstream.fields.checks.passive.unhealthy.timeouts.tooltip': 'Number of timeouts in proxied traffic to consider a target unhealthy, as observed by passive health checks.', + 'component.upstream.fields.checks.passive.unhealthy.timeouts.tooltip': + 'Number of timeouts in proxied traffic to consider a target unhealthy, as observed by passive health checks.', 'component.upstream.other.none': 'None', - 'component.upstream.other.pass_host-with-multiple-nodes.title': 'Please check the target node configuration', - 'component.upstream.other.pass_host-with-multiple-nodes': 'When using a host name or IP in the target node list, make sure there is only one target node', - 'component.upstream.other.health-check.passive-only': 'When passive health check is enabled, active health check needs to be enabled at the same time.', + 'component.upstream.other.pass_host-with-multiple-nodes.title': + 'Please check the target node configuration', + 'component.upstream.other.pass_host-with-multiple-nodes': + 'When using a host name or IP in the target node list, make sure there is only one target node', + 'component.upstream.other.health-check.passive-only': + 'When passive health check is enabled, active health check needs to be enabled at the same time.', 'component.upstream.other.health-check.invalid': 'Please check the health check configuration', -} +}; diff --git a/web/src/components/Upstream/locales/zh-CN.ts b/web/src/components/Upstream/locales/zh-CN.ts index 7e623ecee1..3a803cad86 100644 --- a/web/src/components/Upstream/locales/zh-CN.ts +++ b/web/src/components/Upstream/locales/zh-CN.ts @@ -38,66 +38,85 @@ export default { 'component.upstream.fields.key.tooltip': '哈希键(Hash Key)', 'component.upstream.fields.retries': '重试次数', - 'component.upstream.fields.retries.tooltip': '重试机制将请求发到下一个上游节点。值为 0 表示禁用重试机制,留空表示使用可用后端节点的数量。', + 'component.upstream.fields.retries.tooltip': + '重试机制将请求发到下一个上游节点。值为 0 表示禁用重试机制,留空表示使用可用后端节点的数量。', 'component.upstream.fields.checks.active.type': '类型', - 'component.upstream.fields.checks.active.type.tooltip': '是使用 HTTP 或 HTTPS 进行主动健康检查,还是只尝试 TCP 连接。', + 'component.upstream.fields.checks.active.type.tooltip': + '是使用 HTTP 或 HTTPS 进行主动健康检查,还是只尝试 TCP 连接。', 'component.upstream.fields.checks.active.concurrency': '并行数量', - 'component.upstream.fields.checks.active.concurrency.tooltip': '在主动健康检查中同时检查的目标数量。', + 'component.upstream.fields.checks.active.concurrency.tooltip': + '在主动健康检查中同时检查的目标数量。', 'component.upstream.fields.checks.active.host': '主机名', 'component.upstream.fields.checks.active.host.required': '请输入主机名', - 'component.upstream.fields.checks.active.host.tooltip': '进行主动健康检查时使用的 HTTP 请求主机名', + 'component.upstream.fields.checks.active.host.tooltip': + '进行主动健康检查时使用的 HTTP 请求主机名', 'component.upstream.fields.checks.active.host.scope': '仅支持字母、数字和 . ', 'component.upstream.fields.checks.active.port': '端口', 'component.upstream.fields.checks.active.http_path': '请求路径', - 'component.upstream.fields.checks.active.http_path.tooltip': '向目标节点发出 HTTP GET 请求时应使用的路径。', + 'component.upstream.fields.checks.active.http_path.tooltip': + '向目标节点发出 HTTP GET 请求时应使用的路径。', 'component.upstream.fields.checks.active.http_path.placeholder': '请输入 HTTP 请求路径', 'component.upstream.fields.checks.active.https_verify_certificate': '验证证书', - 'component.upstream.fields.checks.active.https_verify_certificate.tooltip': '在使用 HTTPS 执行主动健康检查时,是否检查远程主机的 SSL 证书的有效性。', + 'component.upstream.fields.checks.active.https_verify_certificate.tooltip': + '在使用 HTTPS 执行主动健康检查时,是否检查远程主机的 SSL 证书的有效性。', 'component.upstream.fields.checks.active.req_headers': '请求头', - 'component.upstream.fields.checks.active.req_headers.tooltip': '额外的请求头,示例:User-Agent: curl/7.29.0', + 'component.upstream.fields.checks.active.req_headers.tooltip': + '额外的请求头,示例:User-Agent: curl/7.29.0', 'component.upstream.fields.checks.active.healthy.interval': '间隔时间', - 'component.upstream.fields.checks.active.healthy.interval.tooltip': '对健康的上游服务目标节点进行主动健康检查的间隔时间(以秒为单位)。数值为0表示对健康节点不进行主动健康检查。', + 'component.upstream.fields.checks.active.healthy.interval.tooltip': + '对健康的上游服务目标节点进行主动健康检查的间隔时间(以秒为单位)。数值为0表示对健康节点不进行主动健康检查。', 'component.upstream.fields.checks.active.healthy.successes': '成功次数', - 'component.upstream.fields.checks.active.healthy.successes.tooltip': '主动健康检查的 HTTP 成功次数,若达到此值,表示上游服务目标节点是健康的。', + 'component.upstream.fields.checks.active.healthy.successes.tooltip': + '主动健康检查的 HTTP 成功次数,若达到此值,表示上游服务目标节点是健康的。', 'component.upstream.fields.checks.active.healthy.successes.required': '请输入成功次数', 'component.upstream.fields.checks.active.healthy.http_statuses': '状态码', - 'component.upstream.fields.checks.active.healthy.http_statuses.tooltip': 'HTTP 状态码列表,当探针在主动健康检查中返回时,视为健康。', + 'component.upstream.fields.checks.active.healthy.http_statuses.tooltip': + 'HTTP 状态码列表,当探针在主动健康检查中返回时,视为健康。', 'component.upstream.fields.checks.active.unhealthy.timeouts': '超时时间', - 'component.upstream.fields.checks.active.unhealthy.timeouts.tooltip': '活动探针中认为目标不健康的超时次数。', + 'component.upstream.fields.checks.active.unhealthy.timeouts.tooltip': + '活动探针中认为目标不健康的超时次数。', 'component.upstream.fields.checks.active.unhealthy.interval': '间隔时间', - 'component.upstream.fields.checks.active.unhealthy.interval.tooltip': '对不健康目标的主动健康检查之间的间隔(以秒为单位)。数值为0表示不应该对健康目标进行主动探查。', + 'component.upstream.fields.checks.active.unhealthy.interval.tooltip': + '对不健康目标的主动健康检查之间的间隔(以秒为单位)。数值为0表示不应该对健康目标进行主动探查。', 'component.upstream.fields.checks.active.unhealthy.required': '请输入间隔时间', 'component.upstream.fields.checks.active.unhealthy.http_failures': 'HTTP 失败次数', - 'component.upstream.fields.checks.active.unhealthy.http_failures.tooltip': '主动健康检查的 HTTP 失败次数,默认值为0。若达到此值,表示上游服务目标节点是不健康的。', - 'component.upstream.fields.checks.active.unhealthy.http_failures.required': '请输入 HTTP 失败次数', + 'component.upstream.fields.checks.active.unhealthy.http_failures.tooltip': + '主动健康检查的 HTTP 失败次数,默认值为0。若达到此值,表示上游服务目标节点是不健康的。', + 'component.upstream.fields.checks.active.unhealthy.http_failures.required': + '请输入 HTTP 失败次数', 'component.upstream.fields.checks.active.unhealthy.tcp_failures': 'TCP 失败次数', - 'component.upstream.fields.checks.active.unhealthy.tcp_failures.tooltip': '主动探测中 TCP 失败次数超过该值时,认为目标不健康。', + 'component.upstream.fields.checks.active.unhealthy.tcp_failures.tooltip': + '主动探测中 TCP 失败次数超过该值时,认为目标不健康。', 'component.upstream.fields.checks.active.unhealthy.tcp_failures.required': '请输入 TCP 失败次数', 'component.upstream.fields.checks.passive.healthy.successes': '成功次数', - 'component.upstream.fields.checks.passive.healthy.successes.tooltip': '通过被动健康检查观察到的正常代理流量的成功次数。如果达到该值,上游服务目标节点将被视为健康。', + 'component.upstream.fields.checks.passive.healthy.successes.tooltip': + '通过被动健康检查观察到的正常代理流量的成功次数。如果达到该值,上游服务目标节点将被视为健康。', 'component.upstream.fields.checks.passive.healthy.successes.required': '请输入成功次数', 'component.upstream.fields.checks.passive.unhealthy.timeouts': '超时时间', - 'component.upstream.fields.checks.passive.unhealthy.timeouts.tooltip': '根据被动健康检查的观察,在代理中认为目标不健康的超时次数。', + 'component.upstream.fields.checks.passive.unhealthy.timeouts.tooltip': + '根据被动健康检查的观察,在代理中认为目标不健康的超时次数。', 'component.upstream.other.none': '不选择(仅在绑定服务时可用)', 'component.upstream.other.pass_host-with-multiple-nodes.title': '请检查目标节点配置', - 'component.upstream.other.pass_host-with-multiple-nodes': '当使用目标节点列表中的主机名或者 IP 时,请确认只有一个目标节点', - 'component.upstream.other.health-check.passive-only': '启用被动健康检查时,需要同时启用主动健康检查。', + 'component.upstream.other.pass_host-with-multiple-nodes': + '当使用目标节点列表中的主机名或者 IP 时,请确认只有一个目标节点', + 'component.upstream.other.health-check.passive-only': + '启用被动健康检查时,需要同时启用主动健康检查。', 'component.upstream.other.health-check.invalid': '请检查健康检查配置', -} +}; diff --git a/web/src/components/Upstream/service.ts b/web/src/components/Upstream/service.ts index 168df8b8d7..ce9359cc85 100644 --- a/web/src/components/Upstream/service.ts +++ b/web/src/components/Upstream/service.ts @@ -21,43 +21,43 @@ import { formatMessage, request } from 'umi'; /** * Because we have some `custom` field in Upstream Form, like custom.tls/custom.checks.active etc, * we need to transform data that doesn't have `custom` field to data contains `custom` field -*/ + */ export const convertToFormData = (originData: UpstreamComponent.ResponseData) => { if (originData === undefined) { // NOTE: When binding Service without Upstream configuration (None), originData === undefined - return undefined + return undefined; } - const data = cloneDeep(originData) - data.custom = {} - data.upstream_id = "Custom" + const data = cloneDeep(originData); + data.custom = {}; + data.upstream_id = 'Custom'; if (data.checks) { - data.custom.checks = {} + data.custom.checks = {}; if (data.checks.active) { - data.custom.checks.active = true + data.custom.checks.active = true; } if (data.checks.passive) { - data.custom.checks.passive = true + data.custom.checks.passive = true; } } if (data.tls) { - data.custom.tls = "enable" + data.custom.tls = 'enable'; } if (data.id) { data.upstream_id = data.id; } - return data -} + return data; +}; /** * Transform Upstream Form data from custom data to API needed data -*/ + */ export const convertToRequestData = ( formData: UpstreamModule.RequestBody, ): UpstreamModule.RequestBody | undefined | { upstream_id: string } => { @@ -71,15 +71,15 @@ export const convertToRequestData = ( nodes, pass_host, upstream_host, - upstream_id = "Custom", - checks + upstream_id = 'Custom', + checks, } = data; - if (!["Custom", "None"].includes(upstream_id)) { + if (!['Custom', 'None'].includes(upstream_id)) { return { upstream_id }; } - data = omit(data, "upstream_id") as any + data = omit(data, 'upstream_id') as any; if (type === 'chash') { if (!hash_on) { @@ -97,10 +97,10 @@ export const convertToRequestData = ( if (checks?.passive && !checks.active) { notification.error({ - message: formatMessage({id: 'component.upstream.other.health-check.invalid'}), - description: formatMessage({id: 'component.upstream.other.health-check.passive-only'}) - }) - return undefined + message: formatMessage({ id: 'component.upstream.other.health-check.invalid' }), + description: formatMessage({ id: 'component.upstream.other.health-check.passive-only' }), + }); + return undefined; } /** @@ -119,8 +119,10 @@ export const convertToRequestData = ( }; export const fetchUpstreamList = () => { - return request>>('/upstreams').then(({ data }) => ({ - data: data.rows.map(row => convertToFormData(row)), - total: data.total_size, - })); + return request>>('/upstreams').then( + ({ data }) => ({ + data: data.rows.map((row) => convertToFormData(row)), + total: data.total_size, + }), + ); }; diff --git a/web/src/components/Upstream/typings.d.ts b/web/src/components/Upstream/typings.d.ts index e7b238290d..dc2cee1ec0 100644 --- a/web/src/components/Upstream/typings.d.ts +++ b/web/src/components/Upstream/typings.d.ts @@ -17,29 +17,29 @@ /** * Schema: https://github.com/apache/apisix/blob/master/apisix/schema_def.lua#L335 -*/ + */ declare namespace UpstreamComponent { - type ActiveCheck = {} + type ActiveCheck = {}; - type PassiveCheck = {} + type PassiveCheck = {}; type TLS = { client_cert: string; - client_key: string - } + client_key: string; + }; type Node = { host: string; port: number; weight: number; priority?: number; - } + }; type Timeout = { connect: number; send: number; read: number; - } + }; type ResponseData = { nodes?: Node[]; @@ -50,7 +50,7 @@ declare namespace UpstreamComponent { checks?: { active?: ActiveCheck; passive?: PassiveCheck; - } + }; hash_on?: string; key?: string; scheme?: string; @@ -64,5 +64,5 @@ declare namespace UpstreamComponent { upstream_id?: string; // NOTE: custom field custom?: Record; - } + }; } diff --git a/web/src/locales/en-US.ts b/web/src/locales/en-US.ts index 049f03dc9e..fa2bfdd7ca 100644 --- a/web/src/locales/en-US.ts +++ b/web/src/locales/en-US.ts @@ -22,11 +22,11 @@ import menu from './en-US/menu'; import pwa from './en-US/pwa'; import settingDrawer from './en-US/settingDrawer'; import settings from './en-US/setting'; -import other from './en-US/other' +import other from './en-US/other'; import Plugin from '../components/Plugin/locales/en-US'; import PluginFlow from '../components/PluginFlow/locales/en-US'; import RawDataEditor from '../components/RawDataEditor/locales/en-US'; -import UpstreamComponent from '../components/Upstream/locales/en-US' +import UpstreamComponent from '../components/Upstream/locales/en-US'; export default { 'navBar.lang': 'Languages', @@ -45,5 +45,5 @@ export default { ...Plugin, ...PluginFlow, ...RawDataEditor, - ...UpstreamComponent + ...UpstreamComponent, }; diff --git a/web/src/locales/en-US/component.ts b/web/src/locales/en-US/component.ts index 71e959b80e..6cf033ab32 100644 --- a/web/src/locales/en-US/component.ts +++ b/web/src/locales/en-US/component.ts @@ -69,7 +69,8 @@ export default { 'component.global.name': 'Name', 'component.global.updateTime': 'Update Time', 'component.global.form.itemExtraMessage.nameGloballyUnique': 'Name should be globally unique', - 'component.global.input.placeholder.description': 'Please enter the description for this route, max 256 characters', + 'component.global.input.placeholder.description': + 'Please enter the description for this route, max 256 characters', // User component 'component.user.loginByPassword': 'Username & Password', 'component.user.login': 'Login', diff --git a/web/src/locales/en-US/menu.ts b/web/src/locales/en-US/menu.ts index e7389b969d..6784959ffb 100644 --- a/web/src/locales/en-US/menu.ts +++ b/web/src/locales/en-US/menu.ts @@ -73,5 +73,5 @@ export default { 'menu.setting': 'Settings', 'menu.serverinfo': 'System Info', 'menu.advanced-feature': 'Advanced', - 'menu.more': 'More' + 'menu.more': 'More', }; diff --git a/web/src/locales/en-US/other.ts b/web/src/locales/en-US/other.ts index 07942ead53..7cb72082bb 100644 --- a/web/src/locales/en-US/other.ts +++ b/web/src/locales/en-US/other.ts @@ -16,4 +16,4 @@ */ export default { 'other.global': 'Global', -} +}; diff --git a/web/src/locales/zh-CN.ts b/web/src/locales/zh-CN.ts index 17487518c1..11a8ec086b 100644 --- a/web/src/locales/zh-CN.ts +++ b/web/src/locales/zh-CN.ts @@ -20,13 +20,13 @@ import component from './zh-CN/component'; import globalHeader from './zh-CN/globalHeader'; import menu from './zh-CN/menu'; import pwa from './zh-CN/pwa'; -import other from './zh-CN/other' +import other from './zh-CN/other'; import settingDrawer from './zh-CN/settingDrawer'; import settings from './zh-CN/setting'; import Plugin from '../components/Plugin/locales/zh-CN'; import PluginFlow from '../components/PluginFlow/locales/zh-CN'; import RawDataEditor from '../components/RawDataEditor/locales/zh-CN'; -import UpstreamComponent from '../components/Upstream/locales/zh-CN' +import UpstreamComponent from '../components/Upstream/locales/zh-CN'; export default { 'navBar.lang': '语言', @@ -45,5 +45,5 @@ export default { ...Plugin, ...PluginFlow, ...RawDataEditor, - ...UpstreamComponent + ...UpstreamComponent, }; diff --git a/web/src/locales/zh-CN/menu.ts b/web/src/locales/zh-CN/menu.ts index d86b7f67c3..4d1ba77c95 100644 --- a/web/src/locales/zh-CN/menu.ts +++ b/web/src/locales/zh-CN/menu.ts @@ -70,5 +70,5 @@ export default { 'menu.setting': '系统设置', 'menu.serverinfo': '系统信息', 'menu.advanced-feature': '高级特性', - 'menu.more': '更多' + 'menu.more': '更多', }; diff --git a/web/src/locales/zh-CN/other.ts b/web/src/locales/zh-CN/other.ts index 145cb0c8a9..36c99f5b86 100644 --- a/web/src/locales/zh-CN/other.ts +++ b/web/src/locales/zh-CN/other.ts @@ -16,4 +16,4 @@ */ export default { 'other.global': '全局', -} +}; diff --git a/web/src/pages/Consumer/List.tsx b/web/src/pages/Consumer/List.tsx index fea131e8cd..a0c9425994 100644 --- a/web/src/pages/Consumer/List.tsx +++ b/web/src/pages/Consumer/List.tsx @@ -21,7 +21,7 @@ import type { ProColumns, ActionType } from '@ant-design/pro-table'; import { Popconfirm, Button, notification } from 'antd'; import { history, useIntl } from 'umi'; import { PlusOutlined } from '@ant-design/icons'; -import querystring from 'query-string' +import querystring from 'query-string'; import { omit } from 'lodash'; import { DELETE_FIELDS } from '@/constants'; @@ -77,12 +77,16 @@ const Page: React.FC = () => { > {formatMessage({ id: 'component.global.edit' })} - { ]; return ( - + actionRef={ref} columns={columns} @@ -131,11 +138,14 @@ const Page: React.FC = () => { {formatMessage({ id: 'component.global.create' })} , - , @@ -143,16 +153,17 @@ const Page: React.FC = () => { /> { setVisible(false) }} + onClose={() => { + setVisible(false); + }} onSubmit={(data: any) => { - (editorMode === 'create' ? create(data) : update(id, data)) - .then(() => { - setVisible(false); - ref.current?.reload(); - }) + (editorMode === 'create' ? create(data) : update(id, data)).then(() => { + setVisible(false); + ref.current?.reload(); + }); }} /> diff --git a/web/src/pages/Consumer/locales/en-US.ts b/web/src/pages/Consumer/locales/en-US.ts index cc2cf0c20e..9fabb8928b 100644 --- a/web/src/pages/Consumer/locales/en-US.ts +++ b/web/src/pages/Consumer/locales/en-US.ts @@ -21,10 +21,11 @@ export default { 'page.consumer.notification.warning.enableAuthenticationPlugin': 'Please enable one authentication plugin', 'page.consumer.username': 'Name', - 'page.consumer.username.required': 'Please enter the Consumer\'s name', + 'page.consumer.username.required': "Please enter the Consumer's name", 'page.consumer.updateTime': 'Update Time', 'page.consumer.list': 'Consumer List', - 'page.consumer.description': 'Consumers are the consumers of Routes, e.g developers, end users, API calls, etc. When creating a consumer, you need to bind at least one Authentication plugin.', + 'page.consumer.description': + 'Consumers are the consumers of Routes, e.g developers, end users, API calls, etc. When creating a consumer, you need to bind at least one Authentication plugin.', 'page.consumer.create': 'Create Consumer', 'page.consumer.configure': 'Configure Consumer', }; diff --git a/web/src/pages/Consumer/locales/zh-CN.ts b/web/src/pages/Consumer/locales/zh-CN.ts index 3c48fc1546..0218657aec 100644 --- a/web/src/pages/Consumer/locales/zh-CN.ts +++ b/web/src/pages/Consumer/locales/zh-CN.ts @@ -23,7 +23,8 @@ export default { 'page.consumer.username.required': '请输入消费者名称', 'page.consumer.updateTime': '更新时间', 'page.consumer.list': '消费者列表', - 'page.consumer.description': '消费者是路由的消费方,形式包括开发者、最终用户、API 调用等。创建消费者时,需绑定至少一个认证类插件。', + 'page.consumer.description': + '消费者是路由的消费方,形式包括开发者、最终用户、API 调用等。创建消费者时,需绑定至少一个认证类插件。', 'page.consumer.create': '创建消费者', 'page.consumer.configure': '配置消费者', }; diff --git a/web/src/pages/PluginTemplate/Create.tsx b/web/src/pages/PluginTemplate/Create.tsx index 8bf3824978..1d15e210b3 100644 --- a/web/src/pages/PluginTemplate/Create.tsx +++ b/web/src/pages/PluginTemplate/Create.tsx @@ -25,7 +25,7 @@ import { transformLableValueToKeyValue } from '@/helpers'; import Step1 from './components/Step1'; import Preview from './components/Preview'; -import { fetchItem, create, update, } from './service'; +import { fetchItem, create, update } from './service'; const Page: React.FC = (props) => { const [step, setStep] = useState(1); @@ -39,8 +39,9 @@ const Page: React.FC = (props) => { fetchItem(id).then(({ data }) => { const { desc, labels = {}, ...rest } = data; form1.setFieldsValue({ - id, desc, custom_normal_labels: Object.keys(labels) - .map((key) => `${key}:${labels[key]}`) + id, + desc, + custom_normal_labels: Object.keys(labels).map((key) => `${key}:${labels[key]}`), }); setPlugins(rest.plugins); }); @@ -50,21 +51,24 @@ const Page: React.FC = (props) => { const onSubmit = () => { const { desc, custom_normal_labels } = form1.getFieldsValue(); const labels: Record = {}; - transformLableValueToKeyValue(custom_normal_labels || []).forEach(({ labelKey, labelValue }) => { - labels[labelKey] = labelValue; - }); + transformLableValueToKeyValue(custom_normal_labels || []).forEach( + ({ labelKey, labelValue }) => { + labels[labelKey] = labelValue; + }, + ); const data = { desc, labels, plugins } as PluginTemplateModule.Entity; const { id } = (props as any).match.params; (id ? update(id, data) : create(data)) .then(() => { notification.success({ - message: `${id - ? formatMessage({ id: 'component.global.edit' }) - : formatMessage({ id: 'component.global.create' }) - } ${formatMessage({ id: 'menu.pluginTemplate' })} ${formatMessage({ - id: 'component.status.success', - })}`, + message: `${ + id + ? formatMessage({ id: 'component.global.edit' }) + : formatMessage({ id: 'component.global.create' }) + } ${formatMessage({ id: 'menu.pluginTemplate' })} ${formatMessage({ + id: 'component.status.success', + })}`, }); history.push('/plugin-template/list'); }) @@ -90,10 +94,11 @@ const Page: React.FC = (props) => { return ( <> @@ -113,7 +118,7 @@ const Page: React.FC = (props) => { onChange={setPlugins} referPage="route" schemaType="route" - /> + /> )} {step === 3 && } diff --git a/web/src/pages/PluginTemplate/List.tsx b/web/src/pages/PluginTemplate/List.tsx index 69f92d1284..14cc247ad5 100644 --- a/web/src/pages/PluginTemplate/List.tsx +++ b/web/src/pages/PluginTemplate/List.tsx @@ -21,7 +21,7 @@ import ProTable from '@ant-design/pro-table'; import type { ActionType, ProColumns } from '@ant-design/pro-table'; import { Button, notification, Popconfirm, Select, Space, Tag } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; -import querystring from 'query-string' +import querystring from 'query-string'; import { fetchList, remove, fetchLabelList } from './service'; @@ -66,13 +66,13 @@ const Page: React.FC = () => { title: formatMessage({ id: 'component.global.labels' }), dataIndex: 'labels', render: (_, record) => { - return Object.keys(record.labels || {}) - .map((item) => ( - - {item}:{record.labels[item]} - - )); - }, renderFormItem: (_, { type }) => { + return Object.keys(record.labels || {}).map((item) => ( + + {item}:{record.labels[item]} + + )); + }, + renderFormItem: (_, { type }) => { if (type === 'form') { return null; } @@ -90,18 +90,20 @@ const Page: React.FC = () => { ); }} > - {Object.keys(labelList) - .map((key) => { - return ( - - {(labelList[key] || []).map((value: string) => ( - - {value} - - ))} - - ); - })} + {Object.keys(labelList).map((key) => { + return ( + + {(labelList[key] || []).map((value: string) => ( + + {value} + + ))} + + ); + })} ); }, @@ -115,7 +117,7 @@ const Page: React.FC = () => { - ) - } + ); + }; const RecordActionDropdown: React.FC<{ record: any }> = ({ record }) => { const tools: { @@ -231,65 +235,68 @@ 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.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: () => { - remove(record.id!).then(() => { - handleTableActionSuccessResponse( - `${formatMessage({ id: 'component.global.delete' })} ${formatMessage({ - id: 'menu.routes', - })} ${formatMessage({ id: 'component.status.success' })}`, - ); - }); - } - }) - } - } - ] + { + 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.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: () => { + remove(record.id!).then(() => { + handleTableActionSuccessResponse( + `${formatMessage({ id: 'component.global.delete' })} ${formatMessage({ + id: 'menu.routes', + })} ${formatMessage({ id: 'component.status.success' })}`, + ); + }); + }, + }); + }, + }, + ]; return ( - - { - tools.map(item => ( + + {tools.map((item) => ( {item.icon && item.icon} {item.name} - )) - } - - }> + ))} + + } + > - ) - } + ); + }; const ListFooter: React.FC = () => { return ( @@ -465,9 +472,9 @@ const Page: React.FC = () => { return ( setResponseBodyMode(mode as string)}> - { - DEBUG_RESPONSE_BODY_MODE_SUPPORTED.map(mode => { - return - }) - } + onSelect={(mode) => setResponseBodyMode(mode as string)} + > + {DEBUG_RESPONSE_BODY_MODE_SUPPORTED.map((mode) => { + return ( + + ); + })} { if (!result) { notification.error({ @@ -453,41 +493,47 @@ const DebugDrawView: React.FC = (props) => { notification.success({ message: formatMessage({ id: 'component.global.copySuccess' }), }); - }}> + }} + > -
+
{ - monaco?.languages.json.jsonDefaults.setDiagnosticsOptions({validate: false}); + monaco?.languages.json.jsonDefaults.setDiagnosticsOptions({ + validate: false, + }); }} options={{ - automaticLayout:true, - scrollbar:{ + automaticLayout: true, + scrollbar: { vertical: 'hidden', horizontal: 'hidden', }, - wordWrap: "on", - minimap: {enabled: false}, + wordWrap: 'on', + minimap: { enabled: false }, readOnly: true, }} />
- {response && Object.keys(response.header) - .map(header => { - return response.header[header].map(value => { - return
{header}: {value}
- }) - }) - } + {response && + Object.keys(response.header).map((header) => { + return response.header[header].map((value) => { + return ( +
+ {header}: {value} +
+ ); + }); + })}
diff --git a/web/src/pages/Route/components/DebugViews/DebugFormDataView.tsx b/web/src/pages/Route/components/DebugViews/DebugFormDataView.tsx index 39e6c8424d..7bedf86879 100644 --- a/web/src/pages/Route/components/DebugViews/DebugFormDataView.tsx +++ b/web/src/pages/Route/components/DebugViews/DebugFormDataView.tsx @@ -28,10 +28,10 @@ const DebugFormDataView: React.FC = (props) => { { label: DebugBodyFormDataValueType.Text, value: DebugBodyFormDataValueType.Text }, { label: DebugBodyFormDataValueType.File, value: DebugBodyFormDataValueType.File }, ]; - const [typeList, setTypeList] = useState({0: DebugBodyFormDataValueType.Text}); + const [typeList, setTypeList] = useState({ 0: DebugBodyFormDataValueType.Text }); const handleTypeChanged = (value: string, index: number) => { - setTypeList({...typeList, [index]: value}) - } + setTypeList({ ...typeList, [index]: value }); + }; const normFile = (e: any) => { if (Array.isArray(e)) { return e; @@ -75,42 +75,45 @@ const DebugFormDataView: React.FC = (props) => { - { + handleTypeChanged(value, index); + }} + data-cy={`debug-formdata-type-${index}`} + /> - { - ( typeList[index] === DebugBodyFormDataValueType.Text || !typeList[index] )&& - ( - - - - ) - } - { - typeList[index] === DebugBodyFormDataValueType.File && - ( - - + + + )} + {typeList[index] === DebugBodyFormDataValueType.File && ( + + - - - - + > + + + - ) - } + + )} {fields.length > 1 && index !== fields.length - 1 && ( diff --git a/web/src/pages/Route/components/DebugViews/DebugParamsView.tsx b/web/src/pages/Route/components/DebugViews/DebugParamsView.tsx index 85fc924836..9a897aebf2 100644 --- a/web/src/pages/Route/components/DebugViews/DebugParamsView.tsx +++ b/web/src/pages/Route/components/DebugViews/DebugParamsView.tsx @@ -27,12 +27,14 @@ const { Option } = AutoComplete; const DebugParamsView: React.FC = (props) => { const { formatMessage } = useIntl(); - const allSelectOptions = props.inputType === "header" ? HEADER_LIST : [] + const allSelectOptions = props.inputType === 'header' ? HEADER_LIST : []; const [result, setResult] = useState(allSelectOptions); const onSearch = (value: string) => { - setResult(allSelectOptions.filter((option) => option.toLowerCase().startsWith(value.toLowerCase()))) - } + setResult( + allSelectOptions.filter((option) => option.toLowerCase().startsWith(value.toLowerCase())), + ); + }; return ( @@ -57,7 +59,8 @@ const DebugParamsView: React.FC = (props) => { + fieldKey={[field.fieldKey, 'key']} + > = (props) => { prevData.params[index].check = true; props.form.setFieldsValue(prevData); } - }}> + }} + > {result.map((value) => (