Skip to content

Commit

Permalink
feat: add copy to clipboard for version numbers (#283)
Browse files Browse the repository at this point in the history
* Add Copy to clipboard button for consumer and provider version

* Move clipboard functionalities to a separate file.

* Add Copy to clipboard to matrix page.

* Add visual cue that the text has been copied

* Remove violated CSS rules

* Initialize copy-to-clipboard functionality with explicit selector

* Rename bootstrap method to reveal better intent.
  • Loading branch information
tancnle authored and bethesque committed Jul 16, 2019
1 parent e5b5f8f commit c10a6f2
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 6 deletions.
1 change: 1 addition & 0 deletions lib/pact_broker/ui/views/index/_css_and_js.haml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
%script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
%script{type: 'text/javascript', src:'/javascripts/material-menu.js'}
%script{type: 'text/javascript', src:'/javascripts/index.js'}
%script{type: 'text/javascript', src:'/javascripts/clipboard.js'}
%script{type: 'text/javascript', src:'/javascripts/jquery-confirm.min.js'}
10 changes: 8 additions & 2 deletions lib/pact_broker/ui/views/index/show-with-tags.haml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@
%a{:href => index_item.consumer_group_url }
= escape_html(index_item.consumer_name)
%td.consumer-version-number
%div
%div.clippable
= escape_html(index_item.consumer_version_number)
%button.clippy.hidden{ title: "Copy to clipboard" }
%span.glyphicon.glyphicon-copy
- if index_item.latest?
.tag.label.label-success
latest
Expand All @@ -56,8 +58,10 @@
%a{ href: index_item.provider_group_url }
= escape_html(index_item.provider_name)
%td.provider-version-number
%div
%div.clippable
= escape_html(index_item.provider_version_number)
%button.clippy.hidden{ title: "Copy to clipboard" }
%span.glyphicon.glyphicon-copy
- index_item.provider_version_latest_tag_names.each do | tag_name |
.tag.label.label-primary
= escape_html(tag_name)
Expand Down Expand Up @@ -85,6 +89,8 @@
});

$(document).ready(function(){
initializeClipper(".clippable");

$("span.pact a").load("/images/doc-text.svg");
$("span.pact-matrix a").load("/images/doc-matrix.svg");
$('td[data-toggle="tooltip"]').each(function(index, td){
Expand Down
14 changes: 12 additions & 2 deletions lib/pact_broker/ui/views/matrix/show.haml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
%script{type: 'text/javascript', src:'/javascripts/jquery-3.3.1.min.js'}
%script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
%script{type: 'text/javascript', src:'/javascripts/matrix.js'}
%script{type: 'text/javascript', src:'/javascripts/clipboard.js'}
%script{type: 'text/javascript', src:'/js/bootstrap.min.js'}

.container
Expand Down Expand Up @@ -102,9 +103,11 @@
%a{href: line.consumer_name_url}
= line.consumer_name
%td.consumer-version{'data-sort-value' => line.consumer_version_order}
%div
%div.clippable
%a{href: line.consumer_version_number_url}
= line.display_consumer_version_number
%button.clippy.hidden{ title: "Copy to clipboard" }
%span.glyphicon.glyphicon-copy
- line.latest_consumer_version_tags.each do | tag |
.tag-parent{"title": tag.tooltip, "data-toggle": "tooltip", "data-placement": "right"}
%a{href: tag.url}
Expand All @@ -126,9 +129,11 @@
%a{href: line.provider_name_url}
= line.provider_name
%td.provider-version{'data-sort-value' => line.provider_version_order}
%div
%div.clippable
%a{href: line.provider_version_number_url}
= line.display_provider_version_number
%button.clippy.hidden{ title: "Copy to clipboard" }
%span.glyphicon.glyphicon-copy
- line.latest_provider_version_tags.each do | tag |
.tag-parent{"title": tag.tooltip, "data-toggle": "tooltip", "data-placement": "right"}
%a{href: tag.url}
Expand All @@ -145,3 +150,8 @@
= "#{line.verification_status} (number #{line.number})"
- else
= line.verification_status

:javascript
$(document).ready(function(){
initializeClipper(".clippable");
});
73 changes: 73 additions & 0 deletions public/javascripts/clipboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Include code to enable copy-to-clipboard functionality
* and currently used on index and matrix tables
* @example in Haml
* %div.clippable
* = Text to be copied
* %button.clippy.hidden{ title: "Copy to clipboard" }
* %span.glyphicon.glyphicon-copy
*/

/**
* Bootstrap copy-to-clipboard functionality
* @param {string} selector CSS selector of elements that require
* copy-to-clipboard functionality
*/
function initializeClipper(selector) {
const elements = $(selector);

elements.hover(function() {
$(this).children(".clippy").toggleClass("hidden");
});

elements
.children(".clippy")
.click(function() {
const clippyButton = $(this);
const text = $.trim(clippyButton.closest(selector).text());

copyToClipboard(text);
flashClipped(clippyButton);
});
}

/**
* Copy text to clipboard using execCommand
* @see https://gist.github.com/Chalarangelo/4ff1e8c0ec03d9294628efbae49216db#file-copytoclipboard-js
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
* @param {string} text text to be copied to clipboard
*/
function copyToClipboard(text) {
const el = document.createElement('textarea');
el.value = text;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);

const selected =
document.getSelection().rangeCount > 0
? document.getSelection().getRangeAt(0)
: false;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
}

/**
* Flash a success tick to indicate successful copy-to-clipboard action
* @param {jQuery Element} clipButton button to copy to clipboard
*/
function flashClipped(clippyButton) {
const icon = clippyButton.children("span");
icon.attr("class", "glyphicon glyphicon-ok success");

setTimeout(
function() { icon.attr("class", "glyphicon glyphicon-copy"); },
2000
);
}
2 changes: 0 additions & 2 deletions public/javascripts/matrix.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

function setTextboxVisibility(selectBox, cssSelector, visibility) {
var textbox = selectBox.closest('.selector').find(cssSelector);
textbox.toggle(visibility);
Expand Down Expand Up @@ -65,7 +64,6 @@ $(document).ready(function(){
}
});


$('[data-toggle="tooltip"]').each(function(index, el){
$(el).tooltip({container: $(el)});
});
Expand Down
19 changes: 19 additions & 0 deletions public/stylesheets/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ body { padding-top: 10px; }
word-wrap: break-word;
}

.clippable {
display: flex;
justify-content: flex-start;
}

.clippy {
padding: 0 4px;
border: none;
background: none;
}

.clippy:hover {
color: #2a6496;
}

.success {
color: #5cb85c
}

span.pact {
display: inline-block;
}
Expand Down

0 comments on commit c10a6f2

Please sign in to comment.