Merge branch 'rs-clone-panel' into 'master'

Add clipboard button for project clone panel

Closes #3585 

Project:

![Screen_Shot_2015-11-24_at_7.34.04_PM](/uploads/8bf73a2816f2525896023c36aea402bc/Screen_Shot_2015-11-24_at_7.34.04_PM.png)

Wiki:

![Screen_Shot_2015-11-24_at_7.34.43_PM](/uploads/ddf400a1c979a1d8b535a34877cd6163/Screen_Shot_2015-11-24_at_7.34.43_PM.png)


See merge request !1896
This commit is contained in:
Dmitriy Zaporozhets 2015-11-30 09:17:39 +00:00
commit 0a1b50ef3f
11 changed files with 135 additions and 79 deletions

View file

@ -1,32 +1,37 @@
#= require clipboard
genericSuccess = (e) ->
showTooltip(e.trigger, 'Copied!')
# Clear the selection and blur the trigger so it loses its border
e.clearSelection()
$(e.trigger).blur()
# Safari doesn't support `execCommand`, so instead we inform the user to
# copy manually.
#
# See http://clipboardjs.com/#browser-support
genericError = (e) ->
if /Mac/i.test(navigator.userAgent)
key = '⌘' # Command
else
key = 'Ctrl'
showTooltip(e.trigger, "Press #{key}-C to copy")
showTooltip = (target, title) ->
$(target).
tooltip(
container: 'body'
html: 'true'
placement: 'auto bottom'
title: title
trigger: 'manual'
).
tooltip('show').
one('mouseleave', -> $(this).tooltip('hide'))
$ ->
clipboard = new Clipboard '.js-clipboard-trigger',
text: (trigger) ->
$target = $(trigger.nextElementSibling || trigger.previousElementSibling)
$target.data('clipboard-text') || $target.text().trim()
clipboard.on 'success', (e) ->
$(e.trigger).
tooltip(trigger: 'manual', placement: 'auto bottom', title: 'Copied!').
tooltip('show').
one('mouseleave', -> $(this).tooltip('hide'))
# Clear the selection and blur the trigger so it loses its border
e.clearSelection()
$(e.trigger).blur()
# Safari doesn't support `execCommand`, so instead we inform the user to
# copy manually.
#
# See http://clipboardjs.com/#browser-support
clipboard.on 'error', (e) ->
if /Mac/i.test(navigator.userAgent)
title = "Press ⌘-C to copy"
else
title = "Press Ctrl-C to copy"
$(e.trigger).
tooltip(trigger: 'manual', placement: 'auto bottom', html: true, title: title).
tooltip('show').
one('mouseleave', -> $(this).tooltip('hide'))
clipboard = new Clipboard '[data-clipboard-target], [data-clipboard-text]'
clipboard.on 'success', genericSuccess
clipboard.on 'error', genericError

View file

@ -1,13 +1,19 @@
class @Project
constructor: ->
# Git clone panel switcher
cloneHolder = $('.git-clone-holder')
if cloneHolder.length
$('a, button', cloneHolder).click ->
$('a, button', cloneHolder).removeClass 'active'
$(@).addClass 'active'
$('#project_clone', cloneHolder).val $(@).data 'clone'
$(".clone").text("").append $(@).data 'clone'
# Git protocol switcher
$('.js-protocol-switch').click ->
return if $(@).hasClass('active')
# Toggle 'active' for both buttons
$('.js-protocol-switch').toggleClass('active')
url = $(@).data('clone')
# Update the input field
$('#project_clone').val(url)
# Update the command line instructions
$('.clone').text(url)
# Ref switcher
$('.project-refs-select').on 'change', ->

View file

@ -90,7 +90,12 @@
}
.visibility-level-label {
@extend .btn;
@extend .btn-gray;
color: $gray;
cursor: auto;
i {
color: inherit;
}
@ -178,6 +183,11 @@
&:active {
outline: none;
}
&.btn-clipboard {
padding-left: 15px;
padding-right: 15px;
}
}
.active {

View file

@ -0,0 +1,58 @@
module ButtonHelper
# Output a "Copy to Clipboard" button
#
# data - Data attributes passed to `content_tag`
#
# Examples:
#
# # Define the clipboard's text
# clipboard_button(clipboard_text: "Foo")
# # => "<button class='...' data-clipboard-text='Foo'>...</button>"
#
# # Define the target element
# clipboard_button(clipboard_target: "#foo")
# # => "<button class='...' data-clipboard-target='#foo'>...</button>"
#
# See http://clipboardjs.com/#usage
def clipboard_button(data = {})
content_tag :button,
icon('clipboard'),
class: 'btn btn-xs btn-clipboard',
data: data,
type: :button
end
def http_clone_button(project)
klass = 'btn js-protocol-switch'
klass << ' active' if default_clone_protocol == 'http'
klass << ' has_tooltip' if current_user.try(:require_password?)
protocol = gitlab_config.protocol.upcase
content_tag :button, protocol,
class: klass,
data: {
clone: project.http_url_to_repo,
container: 'body',
html: 'true',
title: "Set a password on your account<br>to pull or push via #{protocol}"
},
type: :button
end
def ssh_clone_button(project)
klass = 'btn js-protocol-switch'
klass << ' active' if default_clone_protocol == 'ssh'
klass << ' has_tooltip' if current_user.try(:require_ssh_key?)
content_tag :button, 'SSH',
class: klass,
data: {
clone: project.ssh_url_to_repo,
container: 'body',
html: 'true',
title: 'Add an SSH key to your profile<br>to pull or push via SSH.'
},
type: :button
end
end

View file

@ -1,8 +0,0 @@
module ClipboardHelper
def clipboard_button
content_tag :button,
icon('clipboard'),
class: 'btn btn-xs btn-clipboard js-clipboard-trigger',
type: :button
end
end

View file

@ -173,8 +173,7 @@ module ProjectsHelper
'unknown'
end
def default_url_to_repo(project = nil)
project = project || @project
def default_url_to_repo(project = @project)
current_user ? project.url_to_repo : project.http_url_to_repo
end

View file

@ -1,5 +1,5 @@
- empty_repo = @project.empty_repo?
.project-home-panel.clearfix{:class => ("empty-project" if empty_repo)}
.project-home-panel.cover-block.clearfix{:class => ("empty-project" if empty_repo)}
.project-identicon-holder
= project_icon(@project, alt: '', class: 'project-avatar avatar s90')
.project-home-desc
@ -12,8 +12,10 @@
Forked from
= link_to project_path(forked_from_project) do
= forked_from_project.namespace.try(:name)
.cover-controls
.visibility-level-label
= visibility_level_icon(@project.visibility_level)
= visibility_level_label(@project.visibility_level)
.project-repo-buttons
.split-one

View file

@ -20,8 +20,8 @@
- if ci_commit
= render_ci_status(ci_commit)
&nbsp;
= clipboard_button
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id", data: {clipboard_text: commit.id}
= clipboard_button(clipboard_text: commit.id)
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id"
.notes_count
- if note_count > 0

View file

@ -18,9 +18,9 @@
= link_to_member(@project, participant, name: false, size: 24)
.col-md-3
.input-group.cross-project-reference
%span.slead.has_tooltip{title: 'Cross-project reference'}
%span#cross-project-reference.slead.has_tooltip{title: 'Cross-project reference'}
= cross_project_reference(@project, @issue)
= clipboard_button
= clipboard_button(clipboard_target: '#cross-project-reference')
.row
%section.col-md-9

View file

@ -15,9 +15,9 @@
= render "projects/merge_requests/show/participants"
.col-md-3
.input-group.cross-project-reference
%span.slead.has_tooltip{title: 'Cross-project reference'}
%span#cross-project-reference.slead.has_tooltip{title: 'Cross-project reference'}
= cross_project_reference(@project, @merge_request)
= clipboard_button
= clipboard_button(clipboard_target: '#cross-project-reference')
.row
%section.col-md-9

View file

@ -2,25 +2,9 @@
.git-clone-holder.input-group
.input-group-addon.git-protocols
.input-group-btn
%button{ |
type: 'button', |
class: "btn #{ 'active' if default_clone_protocol == 'ssh' }#{ ' has_tooltip' if current_user && current_user.require_ssh_key? }", |
:"data-clone" => project.ssh_url_to_repo, |
:"data-title" => "Add an SSH key to your profile<br> to pull or push via SSH.",
:"data-html" => "true",
:"data-container" => "body"}
SSH
= ssh_clone_button(project)
.input-group-btn
%button{ |
type: 'button', |
class: "btn #{ 'active' if default_clone_protocol == 'http' }#{ ' has_tooltip' if current_user && current_user.require_password? }", |
:"data-clone" => project.http_url_to_repo, |
:"data-title" => "Set a password on your account<br> to pull or push via #{gitlab_config.protocol.upcase}.",
:"data-html" => "true",
:"data-container" => "body"}
= gitlab_config.protocol.upcase
= http_clone_button(project)
= text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true
- if project.kind_of?(Project)
.input-group-addon.has_tooltip{title: "#{visibility_level_label(project.visibility_level)} project", data: { container: "body" } }
.visibility-level-label
= visibility_level_icon(project.visibility_level)
.input-group-btn
= clipboard_button(clipboard_target: '#project_clone')