diff options
Diffstat (limited to 'app/assets/javascripts/integrations/edit/components/integration_form.vue')
-rw-r--r-- | app/assets/javascripts/integrations/edit/components/integration_form.vue | 93 |
1 files changed, 77 insertions, 16 deletions
diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue index 007a384f41e..6e89872ff68 100644 --- a/app/assets/javascripts/integrations/edit/components/integration_form.vue +++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue @@ -3,12 +3,14 @@ import { GlButton, GlModalDirective, GlSafeHtmlDirective as SafeHtml, GlForm } f import axios from 'axios'; import * as Sentry from '@sentry/browser'; import { mapState, mapActions, mapGetters } from 'vuex'; + import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE, I18N_DEFAULT_ERROR_MESSAGE, I18N_SUCCESSFUL_CONNECTION_MESSAGE, integrationLevels, + integrationFormSectionComponents, } from '~/integrations/constants'; import { refreshCurrentPage } from '~/lib/utils/url_utility'; import csrf from '~/lib/utils/csrf'; @@ -33,6 +35,18 @@ export default { DynamicField, ConfirmationModal, ResetConfirmationModal, + IntegrationSectionConnection: () => + import( + /* webpackChunkName: 'integrationSectionConnection' */ '~/integrations/edit/components/sections/connection.vue' + ), + IntegrationSectionJiraIssues: () => + import( + /* webpackChunkName: 'integrationSectionJiraIssues' */ '~/integrations/edit/components/sections/jira_issues.vue' + ), + IntegrationSectionJiraTrigger: () => + import( + /* webpackChunkName: 'integrationSectionJiraTrigger' */ '~/integrations/edit/components/sections/jira_trigger.vue' + ), GlButton, GlForm, }, @@ -41,10 +55,13 @@ export default { SafeHtml, }, mixins: [glFeatureFlagsMixin()], - props: { + provide() { + return { + hasSections: this.hasSections, + }; + }, + inject: { helpHtml: { - type: String, - required: false, default: '', }, }, @@ -81,28 +98,42 @@ export default { disableButtons() { return Boolean(this.isSaving || this.isResetting || this.isTesting); }, - form() { - return this.$refs.integrationForm.$el; + sectionsEnabled() { + return this.glFeatures.integrationFormSections; + }, + hasSections() { + return this.sectionsEnabled && this.customState.sections.length !== 0; + }, + fieldsWithoutSection() { + return this.sectionsEnabled + ? this.propsSource.fields.filter((field) => !field.section) + : this.propsSource.fields; }, }, methods: { ...mapActions(['setOverride', 'requestJiraIssueTypes']), + fieldsForSection(section) { + return this.propsSource.fields.filter((field) => field.section === section.type); + }, + form() { + return this.$refs.integrationForm.$el; + }, setIsValidated() { this.isValidated = true; }, onSaveClick() { this.isSaving = true; - if (this.integrationActive && !this.form.checkValidity()) { + if (this.integrationActive && !this.form().checkValidity()) { this.isSaving = false; this.setIsValidated(); return; } - this.form.submit(); + this.form().submit(); }, onTestClick() { - if (!this.form.checkValidity()) { + if (!this.form().checkValidity()) { this.setIsValidated(); return; } @@ -147,7 +178,7 @@ export default { this.requestJiraIssueTypes(this.getFormData()); }, getFormData() { - return new FormData(this.form); + return new FormData(this.form()); }, onToggleIntegrationState(integrationActive) { this.integrationActive = integrationActive; @@ -159,6 +190,7 @@ export default { FORBID_ATTR: [], // This is trusted input so we can override the default config to allow data-* attributes }, csrf, + integrationFormSectionComponents, }; </script> @@ -187,46 +219,75 @@ export default { @change="setOverride" /> + <template v-if="hasSections"> + <div + v-for="(section, index) in customState.sections" + :key="section.type" + :class="{ 'gl-border-b gl-pb-3 gl-mb-6': index !== customState.sections.length - 1 }" + data-testid="integration-section" + > + <div class="row"> + <div class="col-lg-4"> + <h4 class="gl-mt-0">{{ section.title }}</h4> + <p v-safe-html="section.description"></p> + </div> + + <div class="col-lg-8"> + <component + :is="$options.integrationFormSectionComponents[section.type]" + :fields="fieldsForSection(section)" + :is-validated="isValidated" + @toggle-integration-active="onToggleIntegrationState" + @request-jira-issue-types="onRequestJiraIssueTypes" + /> + </div> + </div> + </div> + </template> + <div class="row"> <div class="col-lg-4"></div> <div class="col-lg-8"> <!-- helpHtml is trusted input --> - <div v-if="helpHtml" v-safe-html:[$options.helpHtmlConfig]="helpHtml"></div> + <div v-if="helpHtml && !hasSections" v-safe-html:[$options.helpHtmlConfig]="helpHtml"></div> <active-checkbox - v-if="propsSource.showActive" + v-if="propsSource.showActive && !hasSections" :key="`${currentKey}-active-checkbox`" @toggle-integration-active="onToggleIntegrationState" /> <jira-trigger-fields - v-if="isJira" + v-if="isJira && !hasSections" :key="`${currentKey}-jira-trigger-fields`" v-bind="propsSource.triggerFieldsProps" :is-validated="isValidated" /> <trigger-fields - v-else-if="propsSource.triggerEvents.length" + v-else-if="propsSource.triggerEvents.length && !hasSections" :key="`${currentKey}-trigger-fields`" :events="propsSource.triggerEvents" :type="propsSource.type" /> <dynamic-field - v-for="field in propsSource.fields" + v-for="field in fieldsWithoutSection" :key="`${currentKey}-${field.name}`" v-bind="field" :is-validated="isValidated" /> <jira-issues-fields - v-if="isJira && !isInstanceOrGroupLevel" + v-if="isJira && !isInstanceOrGroupLevel && !hasSections" :key="`${currentKey}-jira-issues-fields`" v-bind="propsSource.jiraIssuesProps" :is-validated="isValidated" @request-jira-issue-types="onRequestJiraIssueTypes" /> + </div> + </div> + <div v-if="isEditable" class="row"> + <div :class="hasSections ? 'col' : 'col-lg-8 offset-lg-4'"> <div - v-if="isEditable" class="footer-block row-content-block gl-display-flex gl-justify-content-space-between" > <div> |