From f49f23e0d974d632c1e740aae45c357fbf49ab92 Mon Sep 17 00:00:00 2001 From: Makito Date: Fri, 29 Mar 2024 14:02:25 +0800 Subject: [PATCH] fix(entities-plugins): plugin form UX phase 2 --- .../forms/src/generator/FormGenerator.vue | 92 ++- packages/core/forms/src/generator/types.ts | 16 + packages/core/forms/src/index.ts | 1 + packages/core/forms/src/types.ts | 1 + packages/core/forms/tsconfig.json | 3 +- .../src/components/PluginConfigCard.vue | 2 +- .../src/components/PluginEntityForm.vue | 28 +- .../src/components/PluginFieldRuleAlerts.vue | 86 ++ .../src/components/PluginForm.cy.ts | 102 ++- .../src/components/PluginForm.vue | 68 +- .../src/components/PluginIcon.vue | 4 +- .../src/components/PluginList.vue | 2 +- .../entities-plugins/src/composables/index.ts | 3 +- .../src/composables/useI18n.ts | 6 +- .../src/composables/usePluginHelpers.ts | 10 +- .../src/composables/usePluginMeta.ts | 734 +---------------- .../src/composables/useSchemas.ts | 153 ++-- .../src/definitions/metadata.ts | 766 ++++++++++++++++++ .../schemas}/ACL.ts | 0 .../schemas}/AIPromptDecorator.ts | 0 .../schemas}/AIPromptTemplate.ts | 0 .../schemas}/ApplicationRegistration.ts | 0 .../schemas}/ArrayCardContainerFields.ts | 0 .../schemas}/ArrayStringFieldSchema.ts | 0 .../schemas}/BasicAuth.ts | 0 .../schemas}/Datadog.ts | 0 .../schemas}/GraphQLRateLimitingAdvanced.ts | 0 .../schemas}/HMAC.ts | 0 .../schemas}/JWT.ts | 0 .../schemas}/Kafka.ts | 0 .../schemas}/KeyAuth.ts | 0 .../schemas}/KeyAuthEnc.ts | 0 .../schemas}/MetricFields.ts | 0 .../schemas}/Mocking.ts | 0 .../schemas}/OAuth2.ts | 0 .../schemas}/PreFunction.ts | 0 .../schemas}/RateLimiting.ts | 0 .../schemas}/RequestTransformerAdvanced.ts | 0 .../schemas}/RequestValidator.ts | 0 .../schemas}/RouteByHeader.ts | 0 .../schemas}/SAML.ts | 0 .../schemas}/StatsD.ts | 0 .../schemas}/StatsDAdvanced.ts | 0 .../schemas}/VaultAuth.ts | 0 .../schemas}/Zipkin.ts | 0 .../schemas}/credentials/mockedAclSchema.json | 0 .../credentials/mockedBasicAuthSchema.json | 0 .../credentials/mockedHmacAuthSchema.json | 0 .../schemas}/credentials/mockedJwtSchema.json | 0 .../credentials/mockedKeyAuthSchema.json | 0 .../credentials/mockedKeyEncAuthSchema.json | 0 .../credentials/mockedOAuthSchema.json | 0 .../schemas}/typedefs.ts | 0 .../entities/entities-plugins/src/index.ts | 3 +- .../entities-plugins/src/locales/en.json | 22 +- .../entities-plugins/src/types/plugin.ts | 75 +- .../entity-base-form/EntityBaseForm.vue | 8 + 57 files changed, 1313 insertions(+), 872 deletions(-) create mode 100644 packages/core/forms/src/generator/types.ts create mode 100644 packages/core/forms/src/types.ts create mode 100644 packages/entities/entities-plugins/src/components/PluginFieldRuleAlerts.vue create mode 100644 packages/entities/entities-plugins/src/definitions/metadata.ts rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/ACL.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/AIPromptDecorator.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/AIPromptTemplate.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/ApplicationRegistration.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/ArrayCardContainerFields.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/ArrayStringFieldSchema.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/BasicAuth.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/Datadog.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/GraphQLRateLimitingAdvanced.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/HMAC.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/JWT.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/Kafka.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/KeyAuth.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/KeyAuthEnc.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/MetricFields.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/Mocking.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/OAuth2.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/PreFunction.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/RateLimiting.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/RequestTransformerAdvanced.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/RequestValidator.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/RouteByHeader.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/SAML.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/StatsD.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/StatsDAdvanced.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/VaultAuth.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/Zipkin.ts (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/credentials/mockedAclSchema.json (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/credentials/mockedBasicAuthSchema.json (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/credentials/mockedHmacAuthSchema.json (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/credentials/mockedJwtSchema.json (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/credentials/mockedKeyAuthSchema.json (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/credentials/mockedKeyEncAuthSchema.json (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/credentials/mockedOAuthSchema.json (100%) rename packages/entities/entities-plugins/src/{composables/plugin-schemas => definitions/schemas}/typedefs.ts (100%) diff --git a/packages/core/forms/src/generator/FormGenerator.vue b/packages/core/forms/src/generator/FormGenerator.vue index 3fcc3996ad..24f88dae62 100644 --- a/packages/core/forms/src/generator/FormGenerator.vue +++ b/packages/core/forms/src/generator/FormGenerator.vue @@ -30,12 +30,31 @@ :key="`group-${i}`" > + + + + + + + + + + + + + + diff --git a/packages/entities/entities-plugins/src/components/PluginForm.cy.ts b/packages/entities/entities-plugins/src/components/PluginForm.cy.ts index 18395c2d15..9a8025ac29 100644 --- a/packages/entities/entities-plugins/src/components/PluginForm.cy.ts +++ b/packages/entities/entities-plugins/src/components/PluginForm.cy.ts @@ -221,7 +221,7 @@ describe('', () => { cy.get('#config-private_network').should('be.visible') }) - it('should show common, required, and advanced fields when groupFields is true', () => { + it('should show general, hoisted, and advanced fields when groupFields is true', () => { interceptKMSchema({ mockData: schema2 }) cy.mount(PluginForm, { @@ -257,31 +257,42 @@ describe('', () => { cy.get('#route-id').should('be.visible') cy.getTestId('k-collapse-title') - .contains('Common Fields') + .contains('General Configuration') .parents('.k-collapse') .first() - .as('commonFields') + .as('generalFields') cy.getTestId('k-collapse-title') - .contains('Required Fields') + .contains('Plugin Configuration') .parents('.k-collapse') .first() - .as('requiredFields') + .as('pluginFields') - cy.getTestId('k-collapse-title') - .contains('Advanced Fields') - .parents('.k-collapse') - .first() + cy.get('.k-collapse.nested-collapse [data-testid="k-collapse-trigger-label"]') + .contains('Advanced Parameters') + .parents('.k-collapse.nested-collapse') .as('advancedFields') - // common fields - cy.get('@commonFields').find('#enabled').should('exist') - cy.get('@commonFields').find('#instance_name').should('exist') - cy.get('@commonFields').find('#tags').should('exist') - cy.get('@commonFields').find('.plugin-protocols-select').should('be.visible') - - // required fields - cy.get('@requiredFields').find('#config-required_non_checkbox_field').should('be.visible') + // general fields + cy.get('@generalFields').find('#enabled').should('exist') + cy.get('@generalFields').find('#instance_name').should('exist') + cy.get('@generalFields').find('#tags').should('exist') + cy.get('@generalFields').find('.plugin-protocols-select').should('be.visible') + + // field rule alerts + cy.get('@pluginFields').find('.plugin-field-rule-alerts').contains('At least one of').should('be.visible') + + // hoisted fields + cy.get('@pluginFields').find('#config-required_non_checkbox_field').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') + cy.get('@pluginFields').find('#config-api_specification').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') + cy.get('@pluginFields').find('#config-api_specification_filename').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') + cy.get('@pluginFields').find('#config-include_base_path').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') + cy.get('@pluginFields').find('#config-random_status_code').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') // advanced fields should be hidden by default cy.get('@advancedFields').findTestId('k-collapse-hidden-content').should('be.hidden') @@ -291,11 +302,9 @@ describe('', () => { cy.get('@advancedFields').findTestId('k-collapse-hidden-content').should('be.visible') // advanced fields - cy.get('@advancedFields').find('#config-api_specification').should('be.visible') - cy.get('@advancedFields').find('#config-api_specification_filename').should('be.visible') - cy.get('@advancedFields').find('#config-include_base_path').should('be.visible') cy.get('@advancedFields').find('#config-included_status_codes').should('be.visible') - cy.get('@advancedFields').find('#config-random_status_code').should('be.visible') + cy.get('@advancedFields').find('#config-max_delay_time').should('be.visible') + cy.get('@advancedFields').find('#config-min_delay_time').should('be.visible') }) it('should show correct form components for custom plugin with arrays of objects', () => { @@ -966,7 +975,7 @@ describe('', () => { cy.get('#config-private_network').should('be.visible') }) - it('should show common, required, and advanced fields when groupFields is true', () => { + it('should show general, hoisted, and advanced fields when groupFields is true', () => { interceptKonnectSchema({ mockData: schema2 }) cy.mount(PluginForm, { @@ -1003,31 +1012,42 @@ describe('', () => { cy.get('#route-id').should('be.visible') cy.getTestId('k-collapse-title') - .contains('Common Fields') + .contains('General Configuration') .parents('.k-collapse') .first() - .as('commonFields') + .as('generalFields') cy.getTestId('k-collapse-title') - .contains('Required Fields') + .contains('Plugin Configuration') .parents('.k-collapse') .first() - .as('requiredFields') + .as('pluginFields') - cy.getTestId('k-collapse-title') - .contains('Advanced Fields') - .parents('.k-collapse') - .first() + cy.get('.k-collapse.nested-collapse [data-testid="k-collapse-trigger-label"]') + .contains('Advanced Parameters') + .parents('.k-collapse.nested-collapse') .as('advancedFields') - // common fields - cy.get('@commonFields').find('#enabled').should('exist') - cy.get('@commonFields').find('#instance_name').should('exist') - cy.get('@commonFields').find('#tags').should('exist') - cy.get('@commonFields').find('.plugin-protocols-select').should('be.visible') - - // required fields - cy.get('@requiredFields').find('#config-required_non_checkbox_field').should('be.visible') + // general fields + cy.get('@generalFields').find('#enabled').should('exist') + cy.get('@generalFields').find('#instance_name').should('exist') + cy.get('@generalFields').find('#tags').should('exist') + cy.get('@generalFields').find('.plugin-protocols-select').should('be.visible') + + // field rule alerts + cy.get('@pluginFields').find('.plugin-field-rule-alerts').contains('At least one of').should('be.visible') + + // hoisted fields + cy.get('@pluginFields').find('#config-required_non_checkbox_field').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') + cy.get('@pluginFields').find('#config-api_specification').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') + cy.get('@pluginFields').find('#config-api_specification_filename').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') + cy.get('@pluginFields').find('#config-include_base_path').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') + cy.get('@pluginFields').find('#config-random_status_code').should('be.visible') + .parents('.k-collapse.nested-collapse').should('not.exist') // advanced fields should be hidden by default cy.get('@advancedFields').findTestId('k-collapse-hidden-content').should('be.hidden') @@ -1037,11 +1057,9 @@ describe('', () => { cy.get('@advancedFields').findTestId('k-collapse-hidden-content').should('be.visible') // advanced fields - cy.get('@advancedFields').find('#config-api_specification').should('be.visible') - cy.get('@advancedFields').find('#config-api_specification_filename').should('be.visible') - cy.get('@advancedFields').find('#config-include_base_path').should('be.visible') cy.get('@advancedFields').find('#config-included_status_codes').should('be.visible') - cy.get('@advancedFields').find('#config-random_status_code').should('be.visible') + cy.get('@advancedFields').find('#config-max_delay_time').should('be.visible') + cy.get('@advancedFields').find('#config-min_delay_time').should('be.visible') }) it('should show correct form components for custom plugin with arrays of objects', () => { diff --git a/packages/entities/entities-plugins/src/components/PluginForm.vue b/packages/entities/entities-plugins/src/components/PluginForm.vue index e0537f0392..298dc9656b 100644 --- a/packages/entities/entities-plugins/src/components/PluginForm.vue +++ b/packages/entities/entities-plugins/src/components/PluginForm.vue @@ -27,6 +27,7 @@ :fetch-url="fetchUrl" :form-fields="getRequestBody" :is-readonly="form.isReadonly" + no-validate @cancel="handleClickCancel" @fetch:error="(err: any) => $emit('error', err)" @fetch:success="initForm" @@ -131,37 +132,38 @@