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 #= 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', clipboard = new Clipboard '[data-clipboard-target], [data-clipboard-text]'
text: (trigger) -> clipboard.on 'success', genericSuccess
$target = $(trigger.nextElementSibling || trigger.previousElementSibling) clipboard.on 'error', genericError
$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'))

View file

@ -1,13 +1,19 @@
class @Project class @Project
constructor: -> constructor: ->
# Git clone panel switcher # Git protocol switcher
cloneHolder = $('.git-clone-holder') $('.js-protocol-switch').click ->
if cloneHolder.length return if $(@).hasClass('active')
$('a, button', cloneHolder).click ->
$('a, button', cloneHolder).removeClass 'active' # Toggle 'active' for both buttons
$(@).addClass 'active' $('.js-protocol-switch').toggleClass('active')
$('#project_clone', cloneHolder).val $(@).data 'clone'
$(".clone").text("").append $(@).data 'clone' url = $(@).data('clone')
# Update the input field
$('#project_clone').val(url)
# Update the command line instructions
$('.clone').text(url)
# Ref switcher # Ref switcher
$('.project-refs-select').on 'change', -> $('.project-refs-select').on 'change', ->
@ -39,4 +45,4 @@ class @Project
when 4 then label = ' On Mention ' when 4 then label = ' On Mention '
$('#notifications-button').empty().append("<i class='fa fa-bell'></i>" + label + "<i class='fa fa-angle-down'></i>") $('#notifications-button').empty().append("<i class='fa fa-bell'></i>" + label + "<i class='fa fa-angle-down'></i>")
$(@).parents('ul').find('li.active').removeClass 'active' $(@).parents('ul').find('li.active').removeClass 'active'
$(@).parent().addClass 'active' $(@).parent().addClass 'active'

View file

@ -90,7 +90,12 @@
} }
.visibility-level-label { .visibility-level-label {
@extend .btn;
@extend .btn-gray;
color: $gray; color: $gray;
cursor: auto;
i { i {
color: inherit; color: inherit;
} }
@ -178,6 +183,11 @@
&:active { &:active {
outline: none; outline: none;
} }
&.btn-clipboard {
padding-left: 15px;
padding-right: 15px;
}
} }
.active { .active {
@ -552,4 +562,4 @@ pre.light-well {
z-index: 100; z-index: 100;
position: relative; position: relative;
} }
} }

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' 'unknown'
end end
def default_url_to_repo(project = nil) def default_url_to_repo(project = @project)
project = project || @project
current_user ? project.url_to_repo : project.http_url_to_repo current_user ? project.url_to_repo : project.http_url_to_repo
end end

View file

@ -1,5 +1,5 @@
- empty_repo = @project.empty_repo? - 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-identicon-holder
= project_icon(@project, alt: '', class: 'project-avatar avatar s90') = project_icon(@project, alt: '', class: 'project-avatar avatar s90')
.project-home-desc .project-home-desc
@ -12,8 +12,10 @@
Forked from Forked from
= link_to project_path(forked_from_project) do = link_to project_path(forked_from_project) do
= forked_from_project.namespace.try(:name) = 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 .project-repo-buttons
.split-one .split-one
@ -21,7 +23,7 @@
= render 'projects/buttons/fork' = render 'projects/buttons/fork'
= render "shared/clone_panel" = render "shared/clone_panel"
.split-repo-buttons .split-repo-buttons
= render "projects/buttons/download" = render "projects/buttons/download"
= render 'projects/buttons/dropdown' = render 'projects/buttons/dropdown'

View file

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

View file

@ -18,9 +18,9 @@
= link_to_member(@project, participant, name: false, size: 24) = link_to_member(@project, participant, name: false, size: 24)
.col-md-3 .col-md-3
.input-group.cross-project-reference .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) = cross_project_reference(@project, @issue)
= clipboard_button = clipboard_button(clipboard_target: '#cross-project-reference')
.row .row
%section.col-md-9 %section.col-md-9

View file

@ -15,9 +15,9 @@
= render "projects/merge_requests/show/participants" = render "projects/merge_requests/show/participants"
.col-md-3 .col-md-3
.input-group.cross-project-reference .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) = cross_project_reference(@project, @merge_request)
= clipboard_button = clipboard_button(clipboard_target: '#cross-project-reference')
.row .row
%section.col-md-9 %section.col-md-9

View file

@ -2,25 +2,9 @@
.git-clone-holder.input-group .git-clone-holder.input-group
.input-group-addon.git-protocols .input-group-addon.git-protocols
.input-group-btn .input-group-btn
%button{ | = ssh_clone_button(project)
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
.input-group-btn .input-group-btn
%button{ | = http_clone_button(project)
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
= text_field_tag :project_clone, default_url_to_repo(project), class: "js-select-on-focus form-control", readonly: true = 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-btn
.input-group-addon.has_tooltip{title: "#{visibility_level_label(project.visibility_level)} project", data: { container: "body" } } = clipboard_button(clipboard_target: '#project_clone')
.visibility-level-label
= visibility_level_icon(project.visibility_level)