mirror of
https://github.com/GSA/notifications-admin.git
synced 2025-12-10 07:03:12 -05:00
Add API key component
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.
This commit is contained in:
58
app/assets/javascripts/apiKey.js
Normal file
58
app/assets/javascripts/apiKey.js
Normal file
@@ -0,0 +1,58 @@
|
||||
(function(Modules) {
|
||||
"use strict";
|
||||
|
||||
Modules.ApiKey = function() {
|
||||
|
||||
const states = {
|
||||
'initial': `
|
||||
<input type='button' class='api-key-button-show' value='Show API key' />
|
||||
`,
|
||||
'keyVisibleBasic': key => `
|
||||
<span class="api-key-key">${key}</span>
|
||||
`,
|
||||
'keyVisible': key => `
|
||||
<span class="api-key-key">${key}</span>
|
||||
<input type='button' class='api-key-button-copy' value='Copy API key to clipboard' />
|
||||
`,
|
||||
'keyCopied': `
|
||||
<span class="api-key-key">Copied to clipboard</span>
|
||||
<input type='button' class='api-key-button-show' value='Show API key' />
|
||||
`
|
||||
};
|
||||
|
||||
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);
|
||||
17
app/assets/stylesheets/components/api-key.scss
Normal file
17
app/assets/stylesheets/components/api-key.scss
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,6 +45,7 @@
|
||||
@import 'components/management-navigation';
|
||||
@import 'components/dropdown';
|
||||
@import 'components/email-message';
|
||||
@import 'components/api-key';
|
||||
|
||||
@import 'views/job';
|
||||
|
||||
|
||||
5
app/templates/components/api-key.html
Normal file
5
app/templates/components/api-key.html
Normal file
@@ -0,0 +1,5 @@
|
||||
{% macro api_key(key) %}
|
||||
<div data-module="api-key" data-key="{{ key }}">
|
||||
<span class="api-key-key">{{ key }}</span>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
@@ -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) }}
|
||||
|
||||
<h2 class="heading-large">API key</h2>
|
||||
|
||||
{{ api_key('d30512af92e1386d63b90e5973b49a10') }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -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/'))
|
||||
);
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user