From c4544eb8332079d294189586d73a1df48c77f040 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 15 Jan 2016 10:50:10 +0000 Subject: [PATCH] Add API key component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a component for showing an API key. Usage: ```jinja {{ from 'components/api-key.html' import api_key }} {{ api_key('e1b0751388f3cd0fc9982c701acdb3c2') }} ``` Depending on the user’s browser, it works in three different ways. No Javascript --- The API key is shown on the page. Older browsers with Javascript --- The API key is hidden, and users can click a button to reveal it. Newer browsers that support copying to clipboard without Flash --- As above, but when the key is shown there is a button which copies it to the clipboard. This is acheived by using [this polyfill](https://www.npmjs.com/package/query-command-supported) to reliably detect browser support for the ‘copy’ command. The styling of the component is a bit different to the initial sketch. I think a grey button works better than green. Green feels like it’s going to take you somewhere else. --- app/assets/javascripts/apiKey.js | 58 +++++++++++++++++++ .../stylesheets/components/api-key.scss | 17 ++++++ app/assets/stylesheets/main.scss | 1 + app/templates/components/api-key.html | 5 ++ app/templates/views/styleguide.html | 5 ++ gulpfile.babel.js | 10 ++-- package.json | 3 +- 7 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 app/assets/javascripts/apiKey.js create mode 100644 app/assets/stylesheets/components/api-key.scss create mode 100644 app/templates/components/api-key.html diff --git a/app/assets/javascripts/apiKey.js b/app/assets/javascripts/apiKey.js new file mode 100644 index 000000000..30d87278d --- /dev/null +++ b/app/assets/javascripts/apiKey.js @@ -0,0 +1,58 @@ +(function(Modules) { + "use strict"; + + Modules.ApiKey = function() { + + const states = { + 'initial': ` + + `, + 'keyVisibleBasic': key => ` + ${key} + `, + 'keyVisible': key => ` + ${key} + + `, + 'keyCopied': ` + Copied to clipboard + + ` + }; + + this.copyKey = function(keyElement, callback) { + var selection = window.getSelection ? window.getSelection() : document.selection, + range = document.createRange(); + selection.removeAllRanges(); + range.selectNodeContents(keyElement); + selection.addRange(range); + document.execCommand('copy'); + selection.removeAllRanges(); + callback(); + }; + + this.start = function(component) { + + const $component = $(component).html(states.initial).attr('aria-live', 'polite'), + key = $component.data('key'); + + $component + .on( + 'click', '.api-key-button-show', () => + $component.html( + document.queryCommandSupported('copy') ? + states.keyVisible(key) : states.keyVisibleBasic(key) + ) + ) + .on( + 'click', '.api-key-button-copy', () => + this.copyKey( + $('.api-key-key', component)[0], () => + $component.html(states.keyCopied) + ) + ); + + }; + }; + +})(window.GOVUK.Modules); diff --git a/app/assets/stylesheets/components/api-key.scss b/app/assets/stylesheets/components/api-key.scss new file mode 100644 index 000000000..22c787355 --- /dev/null +++ b/app/assets/stylesheets/components/api-key.scss @@ -0,0 +1,17 @@ +.api-key { + + &-key { + font-family: monospace; + display: block; + margin-bottom: 10px; + } + + &-button-show { + @include button($grey-3); + } + + &-button-copy { + @include button($grey-3); + } + +} diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index 2882baaa7..59b450ec7 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -45,6 +45,7 @@ @import 'components/management-navigation'; @import 'components/dropdown'; @import 'components/email-message'; +@import 'components/api-key'; @import 'views/job'; diff --git a/app/templates/components/api-key.html b/app/templates/components/api-key.html new file mode 100644 index 000000000..014136bc4 --- /dev/null +++ b/app/templates/components/api-key.html @@ -0,0 +1,5 @@ +{% macro api_key(key) %} +
+ {{ key }} +
+{% endmacro %} diff --git a/app/templates/views/styleguide.html b/app/templates/views/styleguide.html index 0caefd563..2231b1173 100644 --- a/app/templates/views/styleguide.html +++ b/app/templates/views/styleguide.html @@ -7,6 +7,7 @@ {% from "components/sms-message.html" import sms_message %} {% from "components/table.html" import mapping_table, list_table, row, field %} {% from "components/textbox.html" import textbox %} +{% from "components/api-key.html" import api_key %} {% block page_title %} Styleguide – GOV.UK Notify @@ -152,4 +153,8 @@ {{ textbox(form.password) }} {{ textbox(form.message, highlight_tags=True) }} +

API key

+ + {{ api_key('d30512af92e1386d63b90e5973b49a10') }} + {% endblock %} diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 6c336ce97..5207d6138 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -34,17 +34,19 @@ gulp.task('javascripts', () => gulp .src([ paths.npm + 'govuk_frontend_toolkit/javascripts/govuk/modules.js', paths.npm + 'govuk_frontend_toolkit/javascripts/govuk/selection-buttons.js', - paths.src + 'javascripts/highlightTags.js', + paths.src + 'javascripts/apiKey.js', paths.src + 'javascripts/dropdown.js', + paths.src + 'javascripts/highlightTags.js', paths.src + 'javascripts/main.js' ]) .pipe(plugins.babel({ presets: ['es2015'] })) .pipe(plugins.uglify()) - .pipe(plugins.addSrc.prepend( - './node_modules/jquery/dist/jquery.min.js' - )) + .pipe(plugins.addSrc.prepend([ + paths.npm + 'jquery/dist/jquery.min.js', + paths.npm + 'query-command-supported/dist/queryCommandSupported.min.js' + ])) .pipe(plugins.concat('all.js')) .pipe(gulp.dest(paths.dist + 'javascripts/')) ); diff --git a/package.json b/package.json index 582ad19c2..3f168c228 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "gulp-load-plugins": "1.1.0", "gulp-sass": "2.1.1", "gulp-uglify": "1.5.1", - "jquery": "1.11.2" + "jquery": "1.11.2", + "query-command-supported": "1.0.0" } }