diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 45ce68988..a0aca8a77 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1817,6 +1817,15 @@ module ApplicationHelper ) end + def copy_object_url_link(url, only_icon=false) + link_to_function( + l(:button_copy_link), "copyTextToClipboard(this);", + class: "#{only_icon ? 'icon-only' : 'icon'} icon-copy-link", + data: {'clipboard-text' => url}, + title: (l(:button_copy_link) if only_icon) + ) + end + private def wiki_helper diff --git a/app/helpers/journals_helper.rb b/app/helpers/journals_helper.rb index d947f8233..41769af8c 100644 --- a/app/helpers/journals_helper.rb +++ b/app/helpers/journals_helper.rb @@ -28,9 +28,12 @@ module JournalsHelper # Returns the action links for an issue journal def render_journal_actions(issue, journal, options={}) links = [] + dropbown_links = [] + indice = journal.indice || @journal.issue.visible_journals_with_index.find{|j| j.id == @journal.id}.indice + + dropbown_links << copy_object_url_link(issue_url(issue, anchor: "note-#{indice}", only_path: false)) if journal.notes.present? if options[:reply_links] - indice = journal.indice || @journal.issue.visible_journals_with_index.find{|j| j.id == @journal.id}.indice links << link_to(l(:button_quote), quoted_issue_path(issue, :journal_id => journal, :journal_indice => indice), :remote => true, @@ -47,16 +50,18 @@ module JournalsHelper :title => l(:button_edit), :class => 'icon-only icon-edit' ) - links << link_to(l(:button_delete), + dropbown_links << link_to(l(:button_delete), journal_path(journal, :journal => {:notes => ""}), :remote => true, :method => 'put', :data => {:confirm => l(:text_are_you_sure)}, - :title => l(:button_delete), - :class => 'icon-only icon-del' + :class => 'icon icon-del' ) end end - safe_join(links, ' ') + safe_join(links, ' ') + + actions_dropdown do + safe_join(dropbown_links, ' ') + end end def render_notes(issue, journal, options={}) diff --git a/app/views/issues/_action_menu.html.erb b/app/views/issues/_action_menu.html.erb index bd7bcc05f..a1dcd6312 100644 --- a/app/views/issues/_action_menu.html.erb +++ b/app/views/issues/_action_menu.html.erb @@ -5,9 +5,12 @@ <%= link_to l(:button_log_time), new_issue_time_entry_path(@issue), :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project) %> <%= watcher_link(@issue, User.current) %> -<%= link_to l(:button_copy), project_copy_issue_path(@project, @issue), - :class => 'icon icon-copy' if User.current.allowed_to?(:copy_issues, @project) && Issue.allowed_target_projects.any? %> -<%= link_to l(:button_delete), issue_path(@issue), - :data => {:confirm => issues_destroy_confirmation_message(@issue)}, - :method => :delete, :class => 'icon icon-del' if @issue.deletable? %> +<%= actions_dropdown do %> + <%= copy_object_url_link(issue_url(@issue, only_path: false)) %> + <%= link_to l(:button_copy), project_copy_issue_path(@project, @issue), + :class => 'icon icon-copy' if User.current.allowed_to?(:copy_issues, @project) && Issue.allowed_target_projects.any? %> + <%= link_to l(:button_delete), issue_path(@issue), + :data => {:confirm => issues_destroy_confirmation_message(@issue)}, + :method => :delete, :class => 'icon icon-del' if @issue.deletable? %> +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 00f246f33..20618a89a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1145,6 +1145,7 @@ en: button_change_password: Change password button_copy: Copy button_copy_and_follow: Copy and follow + button_copy_link: Copy link button_annotate: Annotate button_update: Update button_configure: Configure diff --git a/public/images/page_link.png b/public/images/page_link.png new file mode 100644 index 0000000000000000000000000000000000000000..312eab0914ab59271384686255d1be913a6b3add GIT binary patch literal 830 zcmV-E1Ht@>P)VWgGzD=Y79#JI$lhEn`|2MpRa?Bt#-nSD~P0P(mbVe{KrOBoKnSsk>m|ML{6l zBosu@om4j#WzNLRAk+{k1JRvL(MfE&vvbb->v>W{*z*1_uMP}0cIRX*?mz+wk%*#O z%0D-+$B*g1nRkvI+_3E8Pr1NC6@5M&4vWaLCnNlr;lNlr4i91z&)eBGqL{L{GNu;Fof}GS9{gM5BJuH;2QWk8yuOZdB3pGR#s8bd~ zAmt<>3Q=YH$t5YJ5;7@+8Uh6=ktBgY6#6Pa%2F?h910?U8cLT43KAj$Z1*==ra&gILO{WkHfs(--F=bly9l~${z@AT>V$oat!YAD@M zBE0v_F{`g#^wOSP-u~!wvlmXdd*uqFqoZ0^{&nEMDU+=!>({S0wrQhFmoB}Yq1)~0 z^{A)L8Xjzdr(W4_exYO6u3a{4*kIeXZMJUR>Q=ksjW_p!rAwDKYUs90>6Q|C>56o@ zbrSq^Xk7Gq#>dAsn@un`Hz$?w$;Ss`%jV7L%9ShgHFV~C)6M>B`Tp%|nqPc&G*A3| z)Qe+}vT4-x^t1~XE@(6wR;^lPWMo9n*~E!cy~)YRsT2{`?fqeIw-e7N@mOA%UcCIq z_kH(_EK7|>pM*1Wt2^DaDAp|cvp*@(ZZDKpYkKC^?97(`0sb&XTXy7N#sB~S07*qo IM6N<$f;YmCWB>pF literal 0 HcmV?d00001 diff --git a/public/javascripts/application.js b/public/javascripts/application.js index feabd9ca9..d86209c08 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -563,6 +563,23 @@ function randomKey(size) { return key; } +function copyTextToClipboard(target) { + if (target) { + var temp = document.createElement('textarea'); + temp.value = target.getAttribute('data-clipboard-text'); + document.body.appendChild(temp); + temp.select(); + document.execCommand('copy'); + if (temp.parentNode) { + temp.parentNode.removeChild(temp); + } + if ($(target).closest('.drdn.expanded').length) { + $(target).closest('.drdn.expanded').removeClass("expanded"); + } + } + return false; +} + function updateIssueFrom(url, el) { $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){ $(this).data('valuebeforeupdate', $(this).val()); diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index da96a7d8d..d3afe95e8 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -1607,6 +1607,7 @@ td.gantt_selected_column .gantt_hdr,.gantt_selected_column_container { .icon-file.application-pdf { background-image: url(../images/files/pdf.png); } .icon-file.application-zip { background-image: url(../images/files/zip.png); } .icon-file.application-gzip { background-image: url(../images/files/zip.png); } +.icon-copy-link { background-image: url(../images/page_link.png); } .sort-handle.ajax-loading { background-image: url(../images/loading.gif); } tr.ui-sortable-helper { border:1px solid #e4e4e4; }