summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/integrations/edit/components/integration_form.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/integrations/edit/components/integration_form.vue')
-rw-r--r--app/assets/javascripts/integrations/edit/components/integration_form.vue93
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>