Commit 8fb5f42b authored by Markus Koller's avatar Markus Koller

Fix repository clone panel for wikis

This fixes a small bug with wikis where the dropdown label wasn't
updated correctly when switching the protocol.

Since we want to reuse this for group wikis, this also generalizes the
code a bit by:

- Moving the JS initializer into its own file.
- Moving the wiki specs for the clone panel into shared examples, and
  extending it to verify the dropdown switching behaviour.
- Using `container` rather than `project` in variable names.
- Using `repositories` rather than `project code` in UI strings.
- Renaming `enabled_project_button` to `enabled_protocol_button`, to
  make the intent clearer.
parent 4126e9e2
import $ from 'jquery';
export default function initClonePanel() {
const $cloneOptions = $('ul.clone-options-dropdown');
if ($cloneOptions.length) {
const $cloneUrlField = $('#clone_url');
const $cloneBtnLabel = $('.js-git-clone-holder .js-clone-dropdown-label');
const mobileCloneField = document.querySelector(
'.js-mobile-git-clone .js-clone-dropdown-label',
);
const selectedCloneOption = $cloneBtnLabel.text().trim();
if (selectedCloneOption.length > 0) {
$(`a:contains('${selectedCloneOption}')`, $cloneOptions).addClass('is-active');
}
$('a', $cloneOptions).on('click', e => {
e.preventDefault();
const $this = $(e.currentTarget);
const url = $this.attr('href');
const cloneType = $this.data('cloneType');
$('.is-active', $cloneOptions).removeClass('is-active');
$(`a[data-clone-type="${cloneType}"]`).each(function switchProtocol() {
const $el = $(this);
const activeText = $el.find('.dropdown-menu-inner-title').text();
const $container = $el.closest('.js-git-clone-holder, .js-mobile-git-clone');
const $label = $container.find('.js-clone-dropdown-label');
$el.toggleClass('is-active');
$label.text(activeText);
});
if (mobileCloneField) {
mobileCloneField.dataset.clipboardText = url;
} else {
$cloneUrlField.val(url);
}
$('.js-git-empty .js-clone').text(url);
});
}
}
......@@ -9,47 +9,11 @@ import axios from '~/lib/utils/axios_utils';
import { deprecatedCreateFlash as flash } from '~/flash';
import projectSelect from '../../project_select';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import initClonePanel from '~/clone_panel';
export default class Project {
constructor() {
const $cloneOptions = $('ul.clone-options-dropdown');
if ($cloneOptions.length) {
const $projectCloneField = $('#project_clone');
const $cloneBtnLabel = $('.js-git-clone-holder .js-clone-dropdown-label');
const mobileCloneField = document.querySelector(
'.js-mobile-git-clone .js-clone-dropdown-label',
);
const selectedCloneOption = $cloneBtnLabel.text().trim();
if (selectedCloneOption.length > 0) {
$(`a:contains('${selectedCloneOption}')`, $cloneOptions).addClass('is-active');
}
$('a', $cloneOptions).on('click', e => {
e.preventDefault();
const $this = $(e.currentTarget);
const url = $this.attr('href');
const cloneType = $this.data('cloneType');
$('.is-active', $cloneOptions).removeClass('is-active');
$(`a[data-clone-type="${cloneType}"]`).each(function() {
const $el = $(this);
const activeText = $el.find('.dropdown-menu-inner-title').text();
const $container = $el.closest('.project-clone-holder');
const $label = $container.find('.js-clone-dropdown-label');
$el.toggleClass('is-active');
$label.text(activeText);
});
if (mobileCloneField) {
mobileCloneField.dataset.clipboardText = url;
} else {
$projectCloneField.val(url);
}
$('.js-git-empty .js-clone').text(url);
});
}
initClonePanel();
// Ref switcher
if (document.querySelector('.js-project-refs-dropdown')) {
......
......@@ -49,12 +49,12 @@ module ApplicationSettingsHelper
all_protocols_enabled? || Gitlab::CurrentSettings.enabled_git_access_protocol == 'http'
end
def enabled_project_button(project, protocol)
def enabled_protocol_button(container, protocol)
case protocol
when 'ssh'
ssh_clone_button(project, append_link: false)
ssh_clone_button(container, append_link: false)
else
http_clone_button(project, append_link: false)
http_clone_button(container, append_link: false)
end
end
......
......@@ -58,10 +58,10 @@ module ButtonHelper
end
end
def http_clone_button(project, append_link: true)
def http_clone_button(container, append_link: true)
protocol = gitlab_config.protocol.upcase
dropdown_description = http_dropdown_description(protocol)
append_url = project.http_url_to_repo if append_link
append_url = container.http_url_to_repo if append_link
dropdown_item_with_description(protocol, dropdown_description, href: append_url, data: { clone_type: 'http' })
end
......@@ -74,13 +74,13 @@ module ButtonHelper
end
end
def ssh_clone_button(project, append_link: true)
def ssh_clone_button(container, append_link: true)
if Gitlab::CurrentSettings.user_show_add_ssh_key_message? &&
current_user.try(:require_ssh_key?)
dropdown_description = _("You won't be able to pull or push project code via SSH until you add an SSH key to your profile")
dropdown_description = s_("MissingSSHKeyWarningLink|You won't be able to pull or push repositories via SSH until you add an SSH key to your profile")
end
append_url = project.ssh_url_to_repo if append_link
append_url = container.ssh_url_to_repo if append_link
dropdown_item_with_description('SSH', dropdown_description, href: append_url, data: { clone_type: 'ssh' })
end
......
......@@ -12,7 +12,7 @@
%label.label-bold
= _('Clone with SSH')
.input-group
= text_field_tag :ssh_project_clone, project.ssh_url_to_repo, class: "js-select-on-focus form-control qa-ssh-clone-url", readonly: true, aria: { label: 'Project clone URL' }
= text_field_tag :ssh_project_clone, project.ssh_url_to_repo, class: "js-select-on-focus form-control qa-ssh-clone-url", readonly: true, aria: { label: _('Repository clone URL') }
.input-group-append
= clipboard_button(target: '#ssh_project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
......@@ -21,7 +21,7 @@
%label.label-bold
= _('Clone with %{http_label}') % { http_label: gitlab_config.protocol.upcase }
.input-group
= text_field_tag :http_project_clone, project.http_url_to_repo, class: "js-select-on-focus form-control qa-http-clone-url", readonly: true, aria: { label: 'Project clone URL' }
= text_field_tag :http_project_clone, project.http_url_to_repo, class: "js-select-on-focus form-control qa-http-clone-url", readonly: true, aria: { label: _('Repository clone URL') }
.input-group-append
= clipboard_button(target: '#http_project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
......
......@@ -11,7 +11,7 @@
%strong= @wiki.full_path
.pt-3.pt-lg-0.w-100
= render "shared/clone_panel", project: @wiki
= render "shared/clone_panel", container: @wiki
.wiki-git-access
%h3= s_("WikiClone|Install Gollum")
......
- project = project || @project
.git-clone-holder.js-git-clone-holder.input-group
.input-group-prepend
- if allowed_protocols_present?
.input-group-text.clone-dropdown-btn.btn
%span.js-clone-dropdown-label
= enabled_project_button(project, enabled_protocol)
= enabled_protocol_button(container, enabled_protocol)
- else
%a#clone-dropdown.input-group-text.btn.clone-dropdown-btn.qa-clone-dropdown{ href: '#', data: { toggle: 'dropdown' } }
%span.js-clone-dropdown-label
......@@ -13,12 +11,12 @@
= icon('caret-down')
%ul.dropdown-menu.dropdown-menu-selectable.clone-options-dropdown
%li
= ssh_clone_button(project)
= ssh_clone_button(container)
%li
= http_clone_button(project)
= render_if_exists 'shared/kerberos_clone_button', project: project
= http_clone_button(container)
= render_if_exists 'shared/kerberos_clone_button', container: container
= text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true, aria: { label: _('Project clone URL') }
= text_field_tag :clone_url, default_url_to_repo(container), class: "js-select-on-focus form-control", readonly: true, aria: { label: _('Repository clone URL') }
.input-group-append
= clipboard_button(target: '#project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= clipboard_button(target: '#clone_url', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
......@@ -5,7 +5,7 @@
= sprite_icon('close', size: 16, css_class: 'gl-icon')
.gl-alert-body
- translation_params = { protocol: gitlab_config.protocol.upcase, set_password_link: link_to_set_password }
- set_password_message = _("You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account") % translation_params
- set_password_message = _("You won't be able to pull or push repositories via %{protocol} until you %{set_password_link} on your account") % translation_params
= set_password_message.html_safe
.gl-alert-actions
= link_to _('Remind later'), '#', class: 'hide-no-password-message btn gl-alert-action btn-info btn-md gl-button'
......
......@@ -4,7 +4,7 @@
%button{ class: 'gl-alert-dismiss hide-no-ssh-message', type: 'button', 'aria-label': _('Dismiss') }
= sprite_icon('close', css_class: 'gl-icon s16')
.gl-alert-body
= s_("MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile").html_safe
= s_("MissingSSHKeyWarningLink|You won't be able to pull or push repositories via SSH until you add an SSH key to your profile")
.gl-alert-actions
= link_to s_('MissingSSHKeyWarningLink|Add SSH key'), profile_keys_path, class: "btn gl-alert-action btn-warning btn-md new-gl-button"
= link_to s_("MissingSSHKeyWarningLink|Don't show again"), profile_path(user: {hide_no_ssh_key: true}), method: :put, role: 'button', class: 'btn gl-alert-action btn-md btn-warning gl-button btn-warning-secondary'
---
title: Fix repository clone panel for wikis
merge_request: 47676
author:
type: fixed
......@@ -5,38 +5,38 @@ module EE
extend ::Gitlab::Utils::Override
override :ssh_clone_button
def ssh_clone_button(project, append_link: true)
def ssh_clone_button(container, append_link: true)
return super unless ::Gitlab::Geo.secondary?
if ::Gitlab::CurrentSettings.user_show_add_ssh_key_message? &&
current_user.try(:require_ssh_key?)
dropdown_description = _("You won't be able to pull or push project code via SSH until you add an SSH key to your profile")
dropdown_description = s_("MissingSSHKeyWarningLink|You won't be able to pull or push repositories via SSH until you add an SSH key to your profile")
end
append_url = project.ssh_url_to_repo if append_link
geo_url = geo_primary_http_url_to_repo(project)
append_url = container.ssh_url_to_repo if append_link
geo_url = geo_primary_http_url_to_repo(container)
dropdown_item_with_description('SSH', dropdown_description, href: append_url, data: { primary_url: geo_url, clone_type: 'ssh' })
end
override :http_clone_button
def http_clone_button(project, append_link: true)
def http_clone_button(container, append_link: true)
return super unless ::Gitlab::Geo.secondary?
protocol = gitlab_config.protocol.upcase
dropdown_description = http_dropdown_description(protocol)
append_url = project.http_url_to_repo if append_link
geo_url = geo_primary_http_url_to_repo(project)
append_url = container.http_url_to_repo if append_link
geo_url = geo_primary_http_url_to_repo(container)
dropdown_item_with_description(protocol, dropdown_description, href: append_url, data: { primary_url: geo_url, clone_type: 'http' })
end
def kerberos_clone_button(project)
def kerberos_clone_button(container)
klass = 'kerberos-selector has-tooltip'
content_tag :a, 'KRB5',
class: klass,
href: project.kerberos_url_to_repo,
href: container.kerberos_url_to_repo,
data: {
html: 'true',
placement: 'right',
......
......@@ -5,7 +5,7 @@
%label.label-bold
= _('Clone with KRB5')
.input-group
= text_field_tag :kerberos_project_clone, project.kerberos_url_to_repo, class: "js-select-on-focus form-control qa-krb5-clone-url", readonly: true, aria: { label: 'Project clone URL' }
= text_field_tag :kerberos_project_clone, project.kerberos_url_to_repo, class: "js-select-on-focus form-control qa-krb5-clone-url", readonly: true, aria: { label: _('Repository clone URL') }
.input-group-append
= clipboard_button(target: '#kerberos_project_clone', title: _("Copy URL"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
......@@ -11,7 +11,7 @@ RSpec.describe 'shared/_clone_panel' do
shared_examples 'has no geo-specific instructions' do
it 'has no geo-specific instructions' do
render 'shared/clone_panel', project: project
render 'shared/clone_panel', container: project
expect(rendered).not_to match /See Geo-specific instructions/
end
......
......@@ -17656,7 +17656,7 @@ msgstr ""
msgid "MissingSSHKeyWarningLink|Don't show again"
msgstr ""
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push repositories via SSH until you add an SSH key to your profile"
msgstr ""
msgid "ModalButton|Add projects"
......@@ -20940,9 +20940,6 @@ msgstr ""
msgid "Project cannot be shared with the group it is in or one of its ancestors."
msgstr ""
msgid "Project clone URL"
msgstr ""
msgid "Project configuration, excluding integrations"
msgstr ""
......@@ -22908,6 +22905,9 @@ msgstr ""
msgid "Repository cleanup has started. You will receive an email once the cleanup operation is complete."
msgstr ""
msgid "Repository clone URL"
msgstr ""
msgid "Repository files count over the limit"
msgstr ""
......@@ -31175,10 +31175,7 @@ msgstr ""
msgid "You won't be able to create new projects because you have reached your project limit."
msgstr ""
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr ""
msgid "You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
msgid "You won't be able to pull or push repositories via %{protocol} until you %{set_password_link} on your account"
msgstr ""
msgid "You'll be charged for %{true_up_link_start}users over license%{link_end} on a quarterly or annual basis, depending on the terms of your agreement."
......
......@@ -12,7 +12,7 @@ module QA
base.view 'app/views/shared/_clone_panel.html.haml' do
element :clone_dropdown
element :clone_options_dropdown, '.clone-options-dropdown' # rubocop:disable QA/ElementWithPattern
element :project_repository_location, 'text_field_tag :project_clone' # rubocop:disable QA/ElementWithPattern
element :clone_url, 'text_field_tag :clone_url' # rubocop:disable QA/ElementWithPattern
end
end
......@@ -28,7 +28,7 @@ module QA
end
def repository_location
Git::Location.new(find('#project_clone').value)
Git::Location.new(find('#clone_url').value)
end
private
......
......@@ -15,7 +15,7 @@ RSpec.describe 'No Password Alert' do
let(:user) { create(:user) }
it 'shows no alert' do
expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you set a password on your account"
expect(page).not_to have_content "You won't be able to pull or push repositories via HTTP until you set a password on your account"
end
end
......@@ -23,7 +23,7 @@ RSpec.describe 'No Password Alert' do
let(:user) { create(:user, password_automatically_set: true) }
it 'shows a password alert' do
expect(page).to have_content "You won't be able to pull or push project code via HTTP until you set a password on your account"
expect(page).to have_content "You won't be able to pull or push repositories via HTTP until you set a password on your account"
end
end
end
......@@ -41,7 +41,7 @@ RSpec.describe 'No Password Alert' do
gitlab_sign_in_via('saml', user, 'my-uid')
visit project_path(project)
expect(page).to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account"
expect(page).to have_content "You won't be able to pull or push repositories via HTTP until you create a personal access token on your account"
end
end
......@@ -51,7 +51,7 @@ RSpec.describe 'No Password Alert' do
gitlab_sign_in_via('saml', user, 'my-uid')
visit project_path(project)
expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account"
expect(page).not_to have_content "You won't be able to pull or push repositories via HTTP until you create a personal access token on your account"
end
end
end
......@@ -65,7 +65,7 @@ RSpec.describe 'No Password Alert' do
end
it 'shows no alert' do
expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you"
expect(page).not_to have_content "You won't be able to pull or push repositories via HTTP until you"
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Projects > Wiki > User views Git access wiki page' do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, :public) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') }
before do
sign_in(user)
end
it 'Visit Wiki Page Current Commit' do
visit project_wiki_path(project, wiki_page)
click_link 'Clone repository'
expect(page).to have_text("Clone repository #{project.wiki.full_path}")
expect(page).to have_text(project.wiki.http_url_to_repo)
end
end
......@@ -17,4 +17,5 @@ RSpec.describe 'Project wikis' do
it_behaves_like 'User views a wiki page'
it_behaves_like 'User views wiki pages'
it_behaves_like 'User views wiki sidebar'
it_behaves_like 'User views Git access wiki page'
end
......@@ -89,7 +89,7 @@ RSpec.describe ButtonHelper do
it 'shows a warning on the dropdown description' do
description = element.search('.dropdown-menu-inner-content').first
expect(description.inner_text).to eq "You won't be able to pull or push project code via SSH until you add an SSH key to your profile"
expect(description.inner_text).to eq "You won't be able to pull or push repositories via SSH until you add an SSH key to your profile"
end
end
......
# frozen_string_literal: true
RSpec.shared_examples 'User views Git access wiki page' do
let(:wiki_page) { create(:wiki_page, wiki: wiki) }
before do
sign_in(user)
end
it 'shows the correct clone URLs', :js do
visit wiki_page_path(wiki, wiki_page)
click_link 'Clone repository'
expect(page).to have_text("Clone repository #{wiki.full_path}")
within('.git-clone-holder') do
expect(page).to have_css('#clone-dropdown', text: 'HTTP')
expect(page).to have_field('clone_url', with: wiki.http_url_to_repo)
click_link 'HTTP' # open the dropdown
click_link 'SSH' # select the dropdown item
expect(page).to have_css('#clone-dropdown', text: 'SSH')
expect(page).to have_field('clone_url', with: wiki.ssh_url_to_repo)
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