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:
commit
0a1b50ef3f
11 changed files with 135 additions and 79 deletions
|
@ -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'))
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
58
app/helpers/button_helper.rb
Normal file
58
app/helpers/button_helper.rb
Normal 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
|
|
@ -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
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
- if ci_commit
|
- if ci_commit
|
||||||
= render_ci_status(ci_commit)
|
= render_ci_status(ci_commit)
|
||||||
|
|
||||||
= 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
Loading…
Reference in a new issue