Commit 516ee15f authored by Ezekiel Kigbo's avatar Ezekiel Kigbo Committed by Kushal Pandya

Replace the bitbucket import modal with a GlModal

Replaces the haml modal for bitbucket import with a
GlModal. This also extends the shared confirm_modal
with additional props.

Rename how_to_import_link to js-how-to-import-link

Changelog: changed
parent cf9fbb81
<script>
import { GlModal } from '@gitlab/ui';
import { GlModal, GlSafeHtmlDirective } from '@gitlab/ui';
import { __ } from '~/locale';
export default {
cancelAction: { text: __('Cancel') },
directives: {
SafeHtml: GlSafeHtmlDirective,
},
components: {
GlModal,
},
props: {
title: {
type: String,
required: false,
default: '',
},
primaryText: {
type: String,
required: false,
......@@ -18,11 +26,27 @@ export default {
required: false,
default: 'confirm',
},
modalHtmlMessage: {
type: String,
required: false,
default: '',
},
hideCancel: {
type: Boolean,
required: false,
default: false,
},
},
computed: {
primaryAction() {
return { text: this.primaryText, attributes: { variant: this.primaryVariant } };
},
cancelAction() {
return this.hideCancel ? null : this.$options.cancelAction;
},
shouldShowHeader() {
return Boolean(this.title?.length);
},
},
mounted() {
this.$refs.modal.show();
......@@ -36,12 +60,14 @@ export default {
size="sm"
modal-id="confirmationModal"
body-class="gl-display-flex"
:title="title"
:action-primary="primaryAction"
:action-cancel="$options.cancelAction"
hide-header
:action-cancel="cancelAction"
:hide-header="!shouldShowHeader"
@primary="$emit('confirmed')"
@hidden="$emit('closed')"
>
<div class="gl-align-self-center"><slot></slot></div>
<div v-if="!modalHtmlMessage" class="gl-align-self-center"><slot></slot></div>
<div v-else v-safe-html="modalHtmlMessage" class="gl-align-self-center"></div>
</gl-modal>
</template>
import Vue from 'vue';
export function confirmAction(message, { primaryBtnVariant, primaryBtnText } = {}) {
export function confirmAction(
message,
{ primaryBtnVariant, primaryBtnText, modalHtmlMessage, title, hideCancel } = {},
) {
return new Promise((resolve) => {
let confirmed = false;
......@@ -15,6 +18,9 @@ export function confirmAction(message, { primaryBtnVariant, primaryBtnText } = {
props: {
primaryVariant: primaryBtnVariant,
primaryText: primaryBtnText,
title,
modalHtmlMessage,
hideCancel,
},
on: {
confirmed() {
......
import $ from 'jquery';
import { debounce } from 'lodash';
import DEFAULT_PROJECT_TEMPLATES from 'ee_else_ce/projects/default_project_templates';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '../lib/utils/constants';
import axios from '../lib/utils/axios_utils';
import {
......@@ -105,6 +106,21 @@ const deriveProjectPathFromUrl = ($projectImportUrl) => {
};
const bindHowToImport = () => {
const importLinks = document.querySelectorAll('.js-how-to-import-link');
importLinks.forEach((link) => {
const { modalTitle: title, modalMessage: modalHtmlMessage } = link.dataset;
link.addEventListener('click', (e) => {
e.preventDefault();
confirmAction('', {
modalHtmlMessage,
title,
hideCancel: true,
});
});
});
$('.how_to_import_link').on('click', (e) => {
e.preventDefault();
$(e.currentTarget).next('.modal').show();
......
......@@ -430,6 +430,18 @@ module ProjectsHelper
end
end
def import_from_bitbucket_message
link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path("integration/bitbucket") }
str = if current_user.admin?
'ImportProjects|To enable importing projects from Bitbucket, as administrator you need to configure %{link_start}OAuth integration%{link_end}'
else
'ImportProjects|To enable importing projects from Bitbucket, ask your GitLab administrator to configure %{link_start}OAuth integration%{link_end}'
end
s_(str).html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
end
private
def tab_ability_map
......
#bitbucket_import_modal.modal
.modal-dialog
.modal-content
.modal-header
%h3.modal-title Import projects from Bitbucket
%button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
%span{ "aria-hidden": "true" } &times;
.modal-body
To enable importing projects from Bitbucket,
- if current_user.admin?
as administrator you need to configure
- else
ask your GitLab administrator to configure
= link_to 'OAuth integration', help_page_path("integration/bitbucket")
......@@ -22,13 +22,11 @@
- if bitbucket_import_enabled?
%div
= link_to status_import_bitbucket_path, class: "gl-button btn-default btn import_bitbucket js-import-project-btn #{'how_to_import_link' unless bitbucket_import_configured?}",
data: { platform: 'bitbucket_cloud', **tracking_attrs_data(track_label, 'click_button', 'bitbucket_cloud') } do
= link_to status_import_bitbucket_path, class: "gl-button btn-default btn import_bitbucket js-import-project-btn #{'js-how-to-import-link' unless bitbucket_import_configured?}",
data: { modal_title: _("Import projects from Bitbucket"), modal_message: import_from_bitbucket_message, platform: 'bitbucket_cloud', **tracking_attrs_data(track_label, 'click_button', 'bitbucket_cloud') } do
.gl-button-icon
= sprite_icon('bitbucket')
Bitbucket Cloud
- unless bitbucket_import_configured?
= render 'projects/bitbucket_import_modal'
- if bitbucket_server_import_enabled?
%div
= link_to status_import_bitbucket_server_path, class: "gl-button btn-default btn import_bitbucket js-import-project-btn", data: { platform: 'bitbucket_server', **tracking_attrs_data(track_label, 'click_button', 'bitbucket_server') } do
......
......@@ -404,4 +404,47 @@ RSpec.describe 'New project', :js do
end
end
end
context 'from Bitbucket', :js do
shared_examples 'has a link to bitbucket cloud' do
context 'when bitbucket is not configured' do
before do
allow(Gitlab::Auth::OAuth::Provider).to receive(:enabled?).and_call_original
allow(Gitlab::Auth::OAuth::Provider)
.to receive(:enabled?).with(:bitbucket)
.and_return(false)
visit new_project_path
click_link 'Import project'
click_link 'Bitbucket Cloud'
end
it 'shows import instructions' do
expect(find('.modal-body')).to have_content(bitbucket_link_content)
end
end
end
context 'as a user' do
let(:user) { create(:user) }
let(:bitbucket_link_content) { 'To enable importing projects from Bitbucket, ask your GitLab administrator to configure OAuth integration' }
before do
sign_in(user)
end
it_behaves_like 'has a link to bitbucket cloud'
end
context 'as an admin' do
let(:user) { create(:admin) }
let(:bitbucket_link_content) { 'To enable importing projects from Bitbucket, as administrator you need to configure OAuth integration' }
before do
sign_in(user)
end
it_behaves_like 'has a link to bitbucket cloud'
end
end
end
......@@ -6,11 +6,13 @@ describe('Confirm Modal', () => {
let wrapper;
let modal;
const createComponent = ({ primaryText, primaryVariant } = {}) => {
const createComponent = ({ primaryText, primaryVariant, title, hideCancel = false } = {}) => {
wrapper = mount(ConfirmModal, {
propsData: {
primaryText,
primaryVariant,
hideCancel,
title,
},
});
};
......@@ -55,5 +57,19 @@ describe('Confirm Modal', () => {
expect(customProps.text).toBe('OK');
expect(customProps.attributes.variant).toBe('confirm');
});
it('should hide the cancel button if `hideCancel` is set', () => {
createComponent({ hideCancel: true });
const props = findGlModal().props();
expect(props.actionCancel).toBeNull();
});
it('should set the modal title when the `title` prop is set', () => {
const title = 'Modal title';
createComponent({ title });
expect(findGlModal().props().title).toBe(title);
});
});
});
......@@ -1026,4 +1026,26 @@ RSpec.describe ProjectsHelper do
end
end
end
describe '#import_from_bitbucket_message' do
before do
allow(helper).to receive(:current_user).and_return(user)
end
context 'as a user' do
it 'returns a link to contact an administrator' do
allow(user).to receive(:admin?).and_return(false)
expect(helper.import_from_bitbucket_message).to have_text('To enable importing projects from Bitbucket, ask your GitLab administrator to configure OAuth integration')
end
end
context 'as an administrator' do
it 'returns a link to configure bitbucket' do
allow(user).to receive(:admin?).and_return(true)
expect(helper.import_from_bitbucket_message).to have_text('To enable importing projects from Bitbucket, as administrator you need to configure OAuth integration')
end
end
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