Commit 9de9a747 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch 'justin_ho-migrate-integration-form-to-vue' into 'master'

Update ActiveToggle and JiraTriggerFields with new form layout

See merge request gitlab-org/gitlab!32677
parents cc9eff0e 195aad1f
<script> <script>
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import { GlToggle } from '@gitlab/ui'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { GlFormGroup, GlToggle } from '@gitlab/ui';
export default { export default {
name: 'ActiveToggle', name: 'ActiveToggle',
components: { components: {
GlFormGroup,
GlToggle, GlToggle,
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
initialActivated: { initialActivated: {
type: Boolean, type: Boolean,
...@@ -33,7 +36,17 @@ export default { ...@@ -33,7 +36,17 @@ export default {
</script> </script>
<template> <template>
<div> <div v-if="glFeatures.integrationFormRefactor">
<gl-form-group :label="__('Enable integration')" label-for="service[active]">
<gl-toggle
v-model="activated"
name="service[active]"
class="gl-display-block gl-line-height-0"
@change="onToggle"
/>
</gl-form-group>
</div>
<div v-else>
<div class="form-group row" role="group"> <div class="form-group row" role="group">
<label for="service[active]" class="col-form-label col-sm-2">{{ __('Active') }}</label> <label for="service[active]" class="col-form-label col-sm-2">{{ __('Active') }}</label>
<div class="col-sm-10 pt-1"> <div class="col-sm-10 pt-1">
......
<script> <script>
import eventHub from '../event_hub';
import { capitalize, lowerCase, isEmpty } from 'lodash'; import { capitalize, lowerCase, isEmpty } from 'lodash';
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
import { GlFormGroup, GlFormCheckbox, GlFormInput, GlFormSelect, GlFormTextarea } from '@gitlab/ui'; import { GlFormGroup, GlFormCheckbox, GlFormInput, GlFormSelect, GlFormTextarea } from '@gitlab/ui';
...@@ -54,6 +55,7 @@ export default { ...@@ -54,6 +55,7 @@ export default {
data() { data() {
return { return {
model: this.value, model: this.value,
validated: false,
}; };
}, },
computed: { computed: {
...@@ -106,17 +108,35 @@ export default { ...@@ -106,17 +108,35 @@ export default {
name: this.fieldName, name: this.fieldName,
}; };
}, },
valid() {
return !this.required || !isEmpty(this.model) || !this.validated;
},
}, },
created() { created() {
if (this.isNonEmptyPassword) { if (this.isNonEmptyPassword) {
this.model = null; this.model = null;
} }
eventHub.$on('validateForm', this.validateForm);
},
beforeDestroy() {
eventHub.$off('validateForm', this.validateForm);
},
methods: {
validateForm() {
this.validated = true;
},
}, },
}; };
</script> </script>
<template> <template>
<gl-form-group :label="label" :label-for="fieldId" :description="help"> <gl-form-group
:label="label"
:label-for="fieldId"
:invalid-feedback="__('This field is required.')"
:state="valid"
:description="help"
>
<template v-if="isCheckbox"> <template v-if="isCheckbox">
<input :name="fieldName" type="hidden" value="false" /> <input :name="fieldName" type="hidden" value="false" />
<gl-form-checkbox v-model="model" v-bind="sharedProps"> <gl-form-checkbox v-model="model" v-bind="sharedProps">
......
<script> <script>
import { GlFormCheckbox, GlFormRadio } from '@gitlab/ui'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { s__ } from '~/locale';
import { GlFormGroup, GlFormCheckbox, GlFormRadio } from '@gitlab/ui';
const commentDetailOptions = [
{
value: 'standard',
label: s__('Integrations|Standard'),
help: s__('Integrations|Includes commit title and branch'),
},
{
value: 'all_details',
label: s__('Integrations|All details'),
help: s__(
'Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs',
),
},
];
export default { export default {
name: 'JiraTriggerFields', name: 'JiraTriggerFields',
components: { components: {
GlFormGroup,
GlFormCheckbox, GlFormCheckbox,
GlFormRadio, GlFormRadio,
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
initialTriggerCommit: { initialTriggerCommit: {
type: Boolean, type: Boolean,
...@@ -32,13 +51,71 @@ export default { ...@@ -32,13 +51,71 @@ export default {
triggerMergeRequest: this.initialTriggerMergeRequest, triggerMergeRequest: this.initialTriggerMergeRequest,
enableComments: this.initialEnableComments, enableComments: this.initialEnableComments,
commentDetail: this.initialCommentDetail, commentDetail: this.initialCommentDetail,
commentDetailOptions,
}; };
}, },
computed: {
showEnableComments() {
return this.triggerCommit || this.triggerMergeRequest;
},
},
}; };
</script> </script>
<template> <template>
<div class="form-group row pt-2" role="group"> <div v-if="glFeatures.integrationFormRefactor">
<gl-form-group
:label="__('Trigger')"
label-for="service[trigger]"
:description="
s__(
'Integrations|When a Jira issue is mentioned in a commit or merge request a remote link and comment (if enabled) will be created.',
)
"
>
<input name="service[commit_events]" type="hidden" value="false" />
<gl-form-checkbox v-model="triggerCommit" name="service[commit_events]">
{{ __('Commit') }}
</gl-form-checkbox>
<input name="service[merge_requests_events]" type="hidden" value="false" />
<gl-form-checkbox v-model="triggerMergeRequest" name="service[merge_requests_events]">
{{ __('Merge request') }}
</gl-form-checkbox>
</gl-form-group>
<gl-form-group
v-show="showEnableComments"
:label="s__('Integrations|Comment settings:')"
data-testid="comment-settings"
>
<input name="service[comment_on_event_enabled]" type="hidden" value="false" />
<gl-form-checkbox v-model="enableComments" name="service[comment_on_event_enabled]">
{{ s__('Integrations|Enable comments') }}
</gl-form-checkbox>
</gl-form-group>
<gl-form-group
v-show="showEnableComments && enableComments"
:label="s__('Integrations|Comment detail:')"
data-testid="comment-detail"
>
<gl-form-radio
v-for="commentDetailOption in commentDetailOptions"
:key="commentDetailOption.value"
v-model="commentDetail"
:value="commentDetailOption.value"
name="service[comment_detail]"
>
{{ commentDetailOption.label }}
<template #help>
{{ commentDetailOption.help }}
</template>
</gl-form-radio>
</gl-form-group>
</div>
<div v-else class="form-group row pt-2" role="group">
<label for="service[trigger]" class="col-form-label col-sm-2 pt-0">{{ __('Trigger') }}</label> <label for="service[trigger]" class="col-form-label col-sm-2 pt-0">{{ __('Trigger') }}</label>
<div class="col-sm-10"> <div class="col-sm-10">
<label class="weight-normal mb-2"> <label class="weight-normal mb-2">
...@@ -76,20 +153,16 @@ export default { ...@@ -76,20 +153,16 @@ export default {
<label> <label>
{{ s__('Integrations|Comment detail:') }} {{ s__('Integrations|Comment detail:') }}
</label> </label>
<gl-form-radio v-model="commentDetail" value="standard" name="service[comment_detail]"> <gl-form-radio
{{ s__('Integrations|Standard') }} v-for="commentDetailOption in commentDetailOptions"
<template #help> :key="commentDetailOption.value"
{{ s__('Integrations|Includes commit title and branch') }} v-model="commentDetail"
</template> :value="commentDetailOption.value"
</gl-form-radio> name="service[comment_detail]"
<gl-form-radio v-model="commentDetail" value="all_details" name="service[comment_detail]"> >
{{ s__('Integrations|All details') }} {{ commentDetailOption.label }}
<template #help> <template #help>
{{ {{ commentDetailOption.help }}
s__(
'Integrations|Includes Standard plus entire commit message, commit hash, and issue IDs',
)
}}
</template> </template>
</gl-form-radio> </gl-form-radio>
</div> </div>
......
...@@ -45,11 +45,16 @@ export default class IntegrationSettingsForm { ...@@ -45,11 +45,16 @@ export default class IntegrationSettingsForm {
// 2) If this service can be tested // 2) If this service can be tested
// If both conditions are true, we override form submission // If both conditions are true, we override form submission
// and test the service using provided configuration. // and test the service using provided configuration.
if (this.$form.get(0).checkValidity() && this.canTestService) { if (this.$form.get(0).checkValidity()) {
if (this.canTestService) {
e.preventDefault(); e.preventDefault();
// eslint-disable-next-line no-jquery/no-serialize // eslint-disable-next-line no-jquery/no-serialize
this.testSettings(this.$form.serialize()); this.testSettings(this.$form.serialize());
} }
} else {
e.preventDefault();
eventHub.$emit('validateForm');
}
} }
handleServiceToggle() { handleServiceToggle() {
......
...@@ -11,6 +11,9 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -11,6 +11,9 @@ class Projects::ServicesController < Projects::ApplicationController
before_action :web_hook_logs, only: [:edit, :update] before_action :web_hook_logs, only: [:edit, :update]
before_action :set_deprecation_notice_for_prometheus_service, only: [:edit, :update] before_action :set_deprecation_notice_for_prometheus_service, only: [:edit, :update]
before_action :redirect_deprecated_prometheus_service, only: [:update] before_action :redirect_deprecated_prometheus_service, only: [:update]
before_action only: :edit do
push_frontend_feature_flag(:integration_form_refactor)
end
respond_to :html respond_to :html
......
...@@ -8248,6 +8248,9 @@ msgstr "" ...@@ -8248,6 +8248,9 @@ msgstr ""
msgid "Enable header and footer in emails" msgid "Enable header and footer in emails"
msgstr "" msgstr ""
msgid "Enable integration"
msgstr ""
msgid "Enable maintenance mode" msgid "Enable maintenance mode"
msgstr "" msgstr ""
......
...@@ -2,12 +2,10 @@ ...@@ -2,12 +2,10 @@
require 'spec_helper' require 'spec_helper'
describe 'Admin activates Prometheus' do describe 'Admin activates Prometheus', :js do
let(:admin) { create(:user, :admin) } let(:admin) { create(:user, :admin) }
before do before do
stub_feature_flags(integration_form_refactor: false)
sign_in(admin) sign_in(admin)
visit(admin_application_settings_services_path) visit(admin_application_settings_services_path)
......
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'Disable individual triggers' do RSpec.describe 'Disable individual triggers', :js do
include_context 'project service activation' include_context 'project service activation'
let(:checkbox_selector) { 'input[type=checkbox][id$=_events]' } let(:checkbox_selector) { 'input[type=checkbox][name$="_events]"]' }
before do before do
visit_project_integration(service_name) visit_project_integration(service_name)
......
...@@ -23,6 +23,6 @@ RSpec.describe 'User activates Atlassian Bamboo CI' do ...@@ -23,6 +23,6 @@ RSpec.describe 'User activates Atlassian Bamboo CI' do
# Password field should not be filled in. # Password field should not be filled in.
click_link('Atlassian Bamboo CI') click_link('Atlassian Bamboo CI')
expect(find_field('Enter new password').value).to be_blank expect(find_field('Enter new Password').value).to be_blank
end end
end end
...@@ -12,7 +12,7 @@ RSpec.describe 'User activates JetBrains TeamCity CI' do ...@@ -12,7 +12,7 @@ RSpec.describe 'User activates JetBrains TeamCity CI' do
it 'activates service', :js do it 'activates service', :js do
visit_project_integration('JetBrains TeamCity CI') visit_project_integration('JetBrains TeamCity CI')
check('Push') check('Push')
check('Merge request') check('Merge Request')
fill_in('Teamcity url', with: 'http://teamcity.example.com') fill_in('Teamcity url', with: 'http://teamcity.example.com')
fill_in('Build type', with: 'GitlabTest_Build') fill_in('Build type', with: 'GitlabTest_Build')
fill_in('Username', with: 'user') fill_in('Username', with: 'user')
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'User activates Slack notifications' do RSpec.describe 'User activates Slack notifications', :js do
include_context 'project service activation' include_context 'project service activation'
context 'when service is not configured yet' do context 'when service is not configured yet' do
...@@ -10,7 +10,7 @@ RSpec.describe 'User activates Slack notifications' do ...@@ -10,7 +10,7 @@ RSpec.describe 'User activates Slack notifications' do
visit_project_integration('Slack notifications') visit_project_integration('Slack notifications')
end end
it 'activates service', :js do it 'activates service' do
fill_in('Webhook', with: 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685') fill_in('Webhook', with: 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685')
click_test_then_save_integration click_test_then_save_integration
...@@ -38,13 +38,13 @@ RSpec.describe 'User activates Slack notifications' do ...@@ -38,13 +38,13 @@ RSpec.describe 'User activates Slack notifications' do
end end
it 'filters events by channel' do it 'filters events by channel' do
expect(page.find_field('service_push_channel').value).to have_content('1') expect(page.find_field(name: 'service[push_channel]').value).to have_content('1')
expect(page.find_field('service_issue_channel').value).to have_content('2') expect(page.find_field(name: 'service[issue_channel]').value).to have_content('2')
expect(page.find_field('service_merge_request_channel').value).to have_content('3') expect(page.find_field(name: 'service[merge_request_channel]').value).to have_content('3')
expect(page.find_field('service_note_channel').value).to have_content('4') expect(page.find_field(name: 'service[note_channel]').value).to have_content('4')
expect(page.find_field('service_tag_push_channel').value).to have_content('5') expect(page.find_field(name: 'service[tag_push_channel]').value).to have_content('5')
expect(page.find_field('service_pipeline_channel').value).to have_content('6') expect(page.find_field(name: 'service[pipeline_channel]').value).to have_content('6')
expect(page.find_field('service_wiki_page_channel').value).to have_content('7') expect(page.find_field(name: 'service[wiki_page_channel]').value).to have_content('7')
end end
end end
end end
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'Slack slash commands' do RSpec.describe 'Slack slash commands', :js do
include_context 'project service activation' include_context 'project service activation'
before do before do
...@@ -10,7 +10,7 @@ RSpec.describe 'Slack slash commands' do ...@@ -10,7 +10,7 @@ RSpec.describe 'Slack slash commands' do
end end
it 'shows a token placeholder' do it 'shows a token placeholder' do
token_placeholder = find_field('service_token')['placeholder'] token_placeholder = find_field('Token')['placeholder']
expect(token_placeholder).to eq('XXxxXXxxXXxxXXxxXXxxXXxx') expect(token_placeholder).to eq('XXxxXXxxXXxxXXxxXXxxXXxx')
end end
...@@ -19,8 +19,8 @@ RSpec.describe 'Slack slash commands' do ...@@ -19,8 +19,8 @@ RSpec.describe 'Slack slash commands' do
expect(page).to have_content('This service allows users to perform common') expect(page).to have_content('This service allows users to perform common')
end end
it 'redirects to the integrations page after saving but not activating', :js do it 'redirects to the integrations page after saving but not activating' do
fill_in 'service_token', with: 'token' fill_in 'Token', with: 'token'
click_active_toggle click_active_toggle
click_on 'Save' click_on 'Save'
...@@ -28,8 +28,8 @@ RSpec.describe 'Slack slash commands' do ...@@ -28,8 +28,8 @@ RSpec.describe 'Slack slash commands' do
expect(page).to have_content('Slack slash commands settings saved, but not activated.') expect(page).to have_content('Slack slash commands settings saved, but not activated.')
end end
it 'redirects to the integrations page after activating', :js do it 'redirects to the integrations page after activating' do
fill_in 'service_token', with: 'token' fill_in 'Token', with: 'token'
click_on 'Save' click_on 'Save'
expect(current_path).to eq(project_settings_integrations_path(project)) expect(current_path).to eq(project_settings_integrations_path(project))
......
...@@ -5,7 +5,6 @@ shared_context 'project service activation' do ...@@ -5,7 +5,6 @@ shared_context 'project service activation' do
let(:user) { create(:user) } let(:user) { create(:user) }
before do before do
stub_feature_flags(integration_form_refactor: false)
project.add_maintainer(user) project.add_maintainer(user)
sign_in(user) sign_in(user)
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment