hof 20.0.0-beta.9 → 20.0.0-redis-beta.32-redis-beta
Sign up to get free protection for your applications and to get access to all the features.
- package/.github/workflows/automate-publish.yml +1 -1
- package/.github/workflows/automate-tag.yml +4 -4
- package/.nyc_output/cb764db8-e9f0-43bb-b3b1-7af57bb79bb5.json +1 -0
- package/.nyc_output/processinfo/cb764db8-e9f0-43bb-b3b1-7af57bb79bb5.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -1
- package/README.md +329 -256
- package/components/index.js +2 -1
- package/components/notify/index.js +60 -0
- package/components/notify/notify.js +25 -0
- package/config/hof-defaults.js +2 -1
- package/controller/controller.js +14 -4
- package/frontend/template-mixins/mixins/template-mixins.js +7 -3
- package/frontend/template-mixins/partials/forms/checkbox-group.html +10 -1
- package/frontend/template-mixins/partials/forms/input-text-date.html +1 -1
- package/frontend/template-mixins/partials/forms/input-text-group.html +5 -3
- package/frontend/template-mixins/partials/forms/option-group.html +9 -0
- package/frontend/template-mixins/partials/forms/select.html +1 -1
- package/frontend/template-mixins/partials/forms/textarea-group.html +2 -2
- package/frontend/template-partials/views/layout.html +10 -3
- package/frontend/template-partials/views/partials/cookie-banner.html +1 -1
- package/frontend/template-partials/views/partials/form.html +2 -1
- package/frontend/template-partials/views/partials/warn.html +7 -0
- package/frontend/themes/gov-uk/styles/govuk.scss +4 -0
- package/frontend/themes/gov-uk/styles/modules/_validation.scss +2 -2
- package/frontend/toolkit/assets/javascript/form-focus.js +10 -1
- package/frontend/toolkit/assets/javascript/progressive-reveal.js +3 -1
- package/frontend/toolkit/assets/javascript/validation.js +6 -1
- package/lib/health.js +1 -1
- package/lib/sessions.js +1 -1
- package/middleware/rate-limiter.js +3 -1
- package/package.json +4 -3
- package/sandbox/apps/sandbox/fields.js +1 -0
- package/sandbox/apps/sandbox/index.js +1 -5
- package/sandbox/apps/sandbox/translations/en/default.json +36 -15
- package/sandbox/assets/scss/app.scss +0 -52
- package/sandbox/package.json +2 -0
- package/sandbox/public/css/app.css +21 -6666
- package/sandbox/public/js/bundle.js +37 -2793
- package/sandbox/server.js +2 -1
- package/sandbox/yarn.lock +39 -564
- package/.nyc_output/e2fdc3eb-4fd2-47e0-a392-fe5f665776a4.json +0 -1
- package/.nyc_output/processinfo/e2fdc3eb-4fd2-47e0-a392-fe5f665776a4.json +0 -1
- package/.vscode/settings.json +0 -6
- package/frontend/govuk-template/govuk_template_generated.html +0 -104
- package/sandbox/.env +0 -1
package/components/index.js
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const Notify = require('./notify');
|
4
|
+
const Hogan = require('hogan.js');
|
5
|
+
const fs = require('fs');
|
6
|
+
|
7
|
+
module.exports = config => {
|
8
|
+
const notify = new Notify(config);
|
9
|
+
config.parse = config.parse || (data => data);
|
10
|
+
|
11
|
+
if (!config.recipient) {
|
12
|
+
throw new Error('Email recipient must be defined');
|
13
|
+
}
|
14
|
+
if (typeof config.template !== 'string') {
|
15
|
+
throw new Error('Email template must be defined');
|
16
|
+
}
|
17
|
+
|
18
|
+
return superclass => class NotifyBehaviour extends superclass {
|
19
|
+
successHandler(req, res, next) {
|
20
|
+
Promise.resolve()
|
21
|
+
.then(() => {
|
22
|
+
return new Promise((resolve, reject) => {
|
23
|
+
fs.readFile(config.template, (err, template) => err ? reject(err) : resolve(template.toString('utf8')));
|
24
|
+
});
|
25
|
+
})
|
26
|
+
.then(template => {
|
27
|
+
const data = config.parse(req.sessionModel.toJSON(), req.translate);
|
28
|
+
return Hogan.compile(template).render(data);
|
29
|
+
})
|
30
|
+
.then(body => {
|
31
|
+
const settings = { body };
|
32
|
+
|
33
|
+
if (typeof config.recipient === 'function') {
|
34
|
+
settings.recipient = config.recipient(req.sessionModel.toJSON());
|
35
|
+
} else {
|
36
|
+
settings.recipient = req.sessionModel.get(config.recipient) || config.recipient;
|
37
|
+
}
|
38
|
+
if (typeof settings.recipient !== 'string' || !settings.recipient.includes('@')) {
|
39
|
+
throw new Error('hof-behaviour-emailer: invalid recipient');
|
40
|
+
}
|
41
|
+
|
42
|
+
if (typeof config.subject === 'function') {
|
43
|
+
settings.subject = config.subject(req.sessionModel.toJSON(), req.translate);
|
44
|
+
} else {
|
45
|
+
settings.subject = config.subject;
|
46
|
+
}
|
47
|
+
|
48
|
+
return settings;
|
49
|
+
})
|
50
|
+
.then(settings => {
|
51
|
+
return notify.send(settings);
|
52
|
+
})
|
53
|
+
.then(() => {
|
54
|
+
super.successHandler(req, res, next);
|
55
|
+
}, next);
|
56
|
+
}
|
57
|
+
};
|
58
|
+
};
|
59
|
+
|
60
|
+
module.exports.Notify = Notify;
|
@@ -0,0 +1,25 @@
|
|
1
|
+
'use strict';
|
2
|
+
const NotifyClient = require('notifications-node-client').NotifyClient;
|
3
|
+
const {v4: uuidv4} = require('uuid');
|
4
|
+
|
5
|
+
module.exports = class Notify {
|
6
|
+
constructor(opts) {
|
7
|
+
const options = opts || {};
|
8
|
+
this.options = options;
|
9
|
+
this.notifyClient = new NotifyClient(options.notifyApiKey);
|
10
|
+
this.notifyTemplate = options.notifyTemplate;
|
11
|
+
}
|
12
|
+
|
13
|
+
send(email) {
|
14
|
+
const reference = uuidv4();
|
15
|
+
|
16
|
+
return this.notifyClient.sendEmail(this.notifyTemplate, email.recipient, {
|
17
|
+
personalisation: {
|
18
|
+
'email-subject': email.subject,
|
19
|
+
'email-body': email.body
|
20
|
+
},
|
21
|
+
reference });
|
22
|
+
}
|
23
|
+
};
|
24
|
+
|
25
|
+
module.exports.NotifyClient = NotifyClient;
|
package/config/hof-defaults.js
CHANGED
@@ -27,7 +27,8 @@ const defaults = {
|
|
27
27
|
ignoreMiddlewareLogs: ['/healthz'],
|
28
28
|
redis: {
|
29
29
|
port: process.env.REDIS_PORT || '6379',
|
30
|
-
host: process.env.REDIS_HOST || '127.0.0.1'
|
30
|
+
host: process.env.REDIS_HOST || '127.0.0.1',
|
31
|
+
legacyMode: true
|
31
32
|
},
|
32
33
|
session: {
|
33
34
|
ttl: process.env.SESSION_TTL || 1800,
|
package/controller/controller.js
CHANGED
@@ -115,6 +115,7 @@ module.exports = class Controller extends BaseController {
|
|
115
115
|
title: this.getTitle(route, lookup, req.form.options.fields, res.locals),
|
116
116
|
header: this.getHeader(route, lookup, res.locals),
|
117
117
|
captionHeading: this.getCaptionHeading(route, lookup, res.locals),
|
118
|
+
warning: this.getWarning(route, lookup, res.locals),
|
118
119
|
subHeading: this.getSubHeading(route, lookup, res.locals),
|
119
120
|
intro: this.getIntro(route, lookup, res.locals),
|
120
121
|
backLink: this.getBackLink(req, res),
|
@@ -143,6 +144,10 @@ module.exports = class Controller extends BaseController {
|
|
143
144
|
return lookup(`pages.${route}.subHeading`, locals);
|
144
145
|
}
|
145
146
|
|
147
|
+
getWarning(route, lookup, locals) {
|
148
|
+
return lookup(`pages.${route}.warning`, locals);
|
149
|
+
}
|
150
|
+
|
146
151
|
getTitle(route, lookup, fields, locals) {
|
147
152
|
let fieldName = '';
|
148
153
|
if (_.size(fields)) {
|
@@ -166,13 +171,18 @@ module.exports = class Controller extends BaseController {
|
|
166
171
|
Object.keys(req.form.errors).forEach(key => {
|
167
172
|
if (req.form && req.form.options && req.form.options.fields) {
|
168
173
|
const field = req.form.options.fields[key];
|
169
|
-
// get first option for radios
|
170
|
-
if (field.mixin === 'radio-group') {
|
171
|
-
|
174
|
+
// get first option for radios and checkbox
|
175
|
+
if (field.mixin === 'radio-group' || field.mixin === 'checkbox-group') {
|
176
|
+
// get first option for radios and checkbox where there is a toggle
|
177
|
+
if(typeof field.options[0] === 'object') {
|
178
|
+
req.form.errors[key].errorLinkId = key + '-' + field.options[0].value;
|
179
|
+
} else {
|
180
|
+
req.form.errors[key].errorLinkId = key + '-' + field.options[0];
|
181
|
+
}
|
172
182
|
// eslint-disable-next-line brace-style
|
173
183
|
}
|
174
184
|
// get first field for date input control
|
175
|
-
else if (field && field.
|
185
|
+
else if (field && field.mixin === 'input-date') {
|
176
186
|
req.form.errors[key].errorLinkId = key + '-day';
|
177
187
|
} else {
|
178
188
|
req.form.errors[key].errorLinkId = key;
|
@@ -215,6 +215,7 @@ module.exports = function (options) {
|
|
215
215
|
child: field.child,
|
216
216
|
isPageHeading: field.isPageHeading,
|
217
217
|
attributes: field.attributes,
|
218
|
+
isPrefixOrSuffix: _.map(field.attributes, item => {if (item.prefix || item.suffix !== undefined) return true;}),
|
218
219
|
renderChild: renderChild.bind(this)
|
219
220
|
});
|
220
221
|
}
|
@@ -224,6 +225,7 @@ module.exports = function (options) {
|
|
224
225
|
const field = Object.assign({}, this.options.fields[key] || options.fields[key]);
|
225
226
|
const legend = field.legend;
|
226
227
|
const detail = field.detail;
|
228
|
+
const warningValue = 'fields.' + key + '.warning';
|
227
229
|
let legendClassName;
|
228
230
|
let legendValue = 'fields.' + key + '.legend';
|
229
231
|
if (legend) {
|
@@ -241,6 +243,8 @@ module.exports = function (options) {
|
|
241
243
|
legendClassName: legendClassName,
|
242
244
|
role: opts.type === 'radio' ? 'radiogroup' : 'group',
|
243
245
|
isPageHeading: field.isPageHeading,
|
246
|
+
isWarning: field.isWarning,
|
247
|
+
warning: t(warningValue),
|
244
248
|
detail: detail ? detail : '',
|
245
249
|
hint: conditionalTranslate(getTranslationKey(field, key, 'hint')),
|
246
250
|
options: _.map(field.options, function (obj) {
|
@@ -303,7 +307,7 @@ module.exports = function (options) {
|
|
303
307
|
invalid: this.errors && this.errors[key] && opts.required,
|
304
308
|
label: t(fieldLabel || 'fields.' + key + '.label'),
|
305
309
|
selected: selected,
|
306
|
-
className: classNames(field) || '
|
310
|
+
className: classNames(field) || 'govuk-label govuk-checkboxes__label',
|
307
311
|
child: field.child,
|
308
312
|
renderChild: renderChild.bind(this)
|
309
313
|
});
|
@@ -444,8 +448,8 @@ module.exports = function (options) {
|
|
444
448
|
parts.push(dayPart);
|
445
449
|
}
|
446
450
|
|
447
|
-
const monthPart = compiled['partials/forms/input-text-date'].render(inputText.call(this, key + '-month', { pattern: '[0-9]*', min: 1, max: 12, maxlength: 2, hintId: key + '-hint', date: true, autocomplete: autocomplete.month, formGroupClassName, className: classNameMonth,
|
448
|
-
const yearPart = compiled['partials/forms/input-text-date'].render(inputText.call(this, key + '-year', { pattern: '[0-9]*', maxlength: 4, hintId: key + '-hint', date: true, autocomplete: autocomplete.year, formGroupClassName, className: classNameYear,
|
451
|
+
const monthPart = compiled['partials/forms/input-text-date'].render(inputText.call(this, key + '-month', { pattern: '[0-9]*', min: 1, max: 12, maxlength: 2, hintId: key + '-hint', date: true, autocomplete: autocomplete.month, formGroupClassName, className: classNameMonth, isThisRequired }));
|
452
|
+
const yearPart = compiled['partials/forms/input-text-date'].render(inputText.call(this, key + '-year', { pattern: '[0-9]*', maxlength: 4, hintId: key + '-hint', date: true, autocomplete: autocomplete.year, formGroupClassName, className: classNameYear, isThisRequired }));
|
449
453
|
|
450
454
|
return parts.concat(monthPart, yearPart).join('\n');
|
451
455
|
};
|
@@ -5,6 +5,15 @@
|
|
5
5
|
{{legend}}
|
6
6
|
{{#isPageHeading}}</h1>{{/isPageHeading}}
|
7
7
|
</legend>
|
8
|
+
{{#isWarning}}
|
9
|
+
<div class="govuk-warning-text">
|
10
|
+
<span class="govuk-warning-text__icon" aria-hidden="true">!</span>
|
11
|
+
<strong class="govuk-warning-text__text">
|
12
|
+
<span class="govuk-warning-text__assistive">Warning</span>
|
13
|
+
{{warning}}
|
14
|
+
</strong>
|
15
|
+
</div>
|
16
|
+
{{/isWarning}}
|
8
17
|
{{#hint}}<div id="{{key}}-hint" class="govuk-hint">{{hint}}</div>{{/hint}}
|
9
18
|
{{#error}}
|
10
19
|
<p id="{{key}}-error" class="govuk-error-message">
|
@@ -28,7 +37,7 @@
|
|
28
37
|
>
|
29
38
|
<label class="govuk-label govuk-checkboxes__label" for="{{key}}-{{value}}">
|
30
39
|
{{{label}}}
|
31
|
-
{{#optionHint}}<div id="{{key}}-{{value}}-item-hint" class="govuk-hint
|
40
|
+
{{#optionHint}}<div id="{{key}}-{{value}}-item-hint" class="govuk-hint">{{optionHint}}</div>{{/optionHint}}
|
32
41
|
</label>
|
33
42
|
</div>
|
34
43
|
{{#renderChild}}{{/renderChild}}
|
@@ -14,7 +14,7 @@
|
|
14
14
|
type="{{type}}"
|
15
15
|
name="{{id}}"
|
16
16
|
id="{{id}}"
|
17
|
-
class="govuk-input{{#className}} {{className}}{{/className}}{{#error}}
|
17
|
+
class="govuk-input{{#className}} {{className}}{{/className}}{{#error}} govuk-input--error{{/error}}"
|
18
18
|
aria-required="{{required}}"
|
19
19
|
{{#value}} value="{{value}}"{{/value}}
|
20
20
|
{{#min}} min="{{min}}"{{/min}}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div id="{{id}}-group" class="{{#compound}} form-group-compound{{/compound}}{{#formGroupClassName}}{{formGroupClassName}}{{/formGroupClassName}}{{#error}} govuk-form-group--error{{/error}}">
|
2
|
-
{{#isPageHeading}}<h1 class="govuk-label-wrapper">{{/isPageHeading}}<label for="{{id}}" class="{{labelClassName}}">
|
2
|
+
{{#isPageHeading}}<h1 class="govuk-label-wrapper">{{/isPageHeading}}<label for="{{id}}" class="{{labelClassName}}{{#isPageHeading}}govuk-label--l{{/isPageHeading}}">
|
3
3
|
{{{label}}}
|
4
4
|
</label>
|
5
5
|
{{#isPageHeading}}</h1>{{/isPageHeading}}
|
@@ -10,6 +10,7 @@
|
|
10
10
|
</p>
|
11
11
|
{{/error}}
|
12
12
|
{{#renderChild}}{{/renderChild}}
|
13
|
+
{{#isPrefixOrSuffix}}<div class="govuk-input__wrapper">{{/isPrefixOrSuffix}}
|
13
14
|
{{#attributes}}
|
14
15
|
{{#prefix}}
|
15
16
|
<div class="govuk-input__prefix" aria-hidden="true">{{prefix}}</div>
|
@@ -19,7 +20,7 @@
|
|
19
20
|
type="{{type}}"
|
20
21
|
name="{{id}}"
|
21
22
|
id="{{id}}"
|
22
|
-
class="{{^className}}govuk-input{{/className}}{{#className}}{{className}}{{/className}}{{#error}}
|
23
|
+
class="{{^className}}govuk-input{{/className}}{{#className}}{{className}}{{/className}}{{#error}} govuk-input--error{{/error}}"
|
23
24
|
aria-required="{{required}}"
|
24
25
|
{{#value}} value="{{value}}"{{/value}}
|
25
26
|
{{#min}} min="{{min}}"{{/min}}
|
@@ -35,7 +36,8 @@
|
|
35
36
|
>
|
36
37
|
{{#attributes}}
|
37
38
|
{{#suffix}}
|
38
|
-
<div class="govuk-
|
39
|
+
<div class="govuk-input__suffix" aria-hidden="true">{{suffix}}</div>
|
39
40
|
{{/suffix}}
|
40
41
|
{{/attributes}}
|
42
|
+
{{#isPrefixOrSuffix}}</div>{{/isPrefixOrSuffix}}
|
41
43
|
</div>
|
@@ -5,6 +5,15 @@
|
|
5
5
|
{{legend}}
|
6
6
|
{{#isPageHeading}}</h1>{{/isPageHeading}}
|
7
7
|
</legend>
|
8
|
+
{{#isWarning}}
|
9
|
+
<div class="govuk-warning-text">
|
10
|
+
<span class="govuk-warning-text__icon" aria-hidden="true">!</span>
|
11
|
+
<strong class="govuk-warning-text__text">
|
12
|
+
<span class="govuk-warning-text__assistive">Warning</span>
|
13
|
+
{{warning}}
|
14
|
+
</strong>
|
15
|
+
</div>
|
16
|
+
{{/isWarning}}
|
8
17
|
{{#hint}}<div id="{{key}}-hint" class="govuk-hint">{{hint}}</div>{{/hint}}
|
9
18
|
{{#error}}<p id="{{key}}-error" class="govuk-error-message"><span class="govuk-visually-hidden">Error:</span> {{error.message}}</p>{{/error}}
|
10
19
|
{{{detail}}}
|
@@ -9,7 +9,7 @@
|
|
9
9
|
{{/error}}
|
10
10
|
</label>
|
11
11
|
{{#isPageHeading}}</h1>{{/isPageHeading}}
|
12
|
-
<select id="{{id}}" class="govuk-select{{#className}} {{className}}{{/className}}{{#error}}
|
12
|
+
<select id="{{id}}" class="govuk-select{{#className}} {{className}}{{/className}}{{#error}} govuk-select--error{{/error}}" name="{{id}}" aria-required="{{required}}">
|
13
13
|
{{#options}}
|
14
14
|
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{label}}</option>
|
15
15
|
{{/options}}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class="govuk-character-count" data-module="govuk-character-count" data-maxlength="{{maxlength}}">
|
3
3
|
{{/maxlength}}
|
4
4
|
<div id="{{id}}-group" class="{{#compound}}form-group-compound {{/compound}}{{#formGroupClassName}}{{formGroupClassName}}{{/formGroupClassName}}{{#error}} govuk-form-group--error{{/error}}">
|
5
|
-
{{#isPageHeading}}<h1 class="govuk-label-wrapper">{{/isPageHeading}}<label for="{{id}}" class="{{labelClassName}}">
|
5
|
+
{{#isPageHeading}}<h1 class="govuk-label-wrapper">{{/isPageHeading}}<label for="{{id}}" class="{{labelClassName}}{{#isPageHeading}}govuk-label--l{{/isPageHeading}}">
|
6
6
|
{{{label}}}
|
7
7
|
{{#error}}
|
8
8
|
<p id="{{id}}-error" class="govuk-error-message">
|
@@ -16,7 +16,7 @@
|
|
16
16
|
<textarea
|
17
17
|
name="{{id}}"
|
18
18
|
id="{{id}}"
|
19
|
-
class="govuk-textarea{{#className}} {{className}}{{/className}} {{#maxlength}}maxlength{{/maxlength}}{{#error}}
|
19
|
+
class="govuk-textarea{{#className}} {{className}}{{/className}} {{#maxlength}}maxlength{{/maxlength}}{{#error}} govuk-input--error{{/error}}"
|
20
20
|
aria-required="{{required}}"
|
21
21
|
{{#maxlength}} maxlength="{{maxlength}}"{{/maxlength}}
|
22
22
|
{{#attributes}}
|
@@ -44,9 +44,16 @@
|
|
44
44
|
{{/gaTagId}}
|
45
45
|
{{/cookieMessage}}
|
46
46
|
{{$footerSupportLinks}}
|
47
|
-
<
|
48
|
-
|
49
|
-
|
47
|
+
<ul>
|
48
|
+
{{#footerSupportLinks}}
|
49
|
+
<li class="govuk-footer__inline-list-item"><a href="{{path}}">{{#t}}{{property}}{{/t}}</a></li>
|
50
|
+
{{/footerSupportLinks}}
|
51
|
+
{{^footerSupportLinks}}
|
52
|
+
<li class="govuk-footer__inline-list-item"><a class="govuk-footer__link" href="/cookies">{{#t}}base.cookies{{/t}}</a></li>
|
53
|
+
<li class="govuk-footer__inline-list-item"><a class="govuk-footer__link" href="/accessibility">{{#t}}base.accessibility{{/t}}</a></li>
|
54
|
+
<li class="govuk-footer__inline-list-item"><a class="govuk-footer__link" href="/terms-and-conditions">{{#t}}base.terms{{/t}}</a></li>
|
55
|
+
{{/footerSupportLinks}}
|
56
|
+
</ul>
|
50
57
|
{{/footerSupportLinks}}
|
51
58
|
{{$bodyEnd}}
|
52
59
|
{{> partials-gatag}}
|
@@ -20,7 +20,7 @@
|
|
20
20
|
</div>
|
21
21
|
<div class="gem-c-cookie-banner__confirmation govuk-width-container" tabindex="0" hidden="" id="cookie-banner-submitted" >
|
22
22
|
<p class="gem-c-cookie-banner__confirmation-message" role="alert">
|
23
|
-
Your cookie preferences have been saved. You can <a class="govuk-link" data-module="gem-track-click" data-track-category="cookieBanner" data-track-action="Cookie banner settings clicked from confirmation" href="/
|
23
|
+
Your cookie preferences have been saved. You can <a class="govuk-link" data-module="gem-track-click" data-track-category="cookieBanner" data-track-action="Cookie banner settings clicked from confirmation" href="/cookies">change your cookie settings</a> at any time.
|
24
24
|
</p>
|
25
25
|
<div class="govuk-button-group">
|
26
26
|
<button class="gem-c-cookie-banner__hide-button govuk-button" id="hide-cookie-banner">Hide this message</button>
|
@@ -1,7 +1,8 @@
|
|
1
1
|
<form action="" method="POST" {{$encoding}}{{/encoding}} autocomplete="off" novalidate="true" spellcheck="false">
|
2
2
|
{{$intro}}
|
3
|
-
{{#intro}}<
|
3
|
+
{{#intro}}<p>{{intro}}</p>{{/intro}}
|
4
4
|
{{/intro}}
|
5
|
+
|
5
6
|
{{$form}}{{/form}}
|
6
7
|
{{#csrf-token}}
|
7
8
|
<input type="hidden" name="x-csrf-token" value="{{csrf-token}}" />
|
@@ -12,6 +12,10 @@ $path: "/public/images/" !default;
|
|
12
12
|
// https://github.com/alphagov/govuk_elements/blob/master/packages/govuk-elements-sass/public/sass/_elements.scss
|
13
13
|
@import "govuk-elements-sass/public/sass/elements";
|
14
14
|
|
15
|
+
// Govuk frontend
|
16
|
+
// https://github.com/alphagov/govuk-frontend-docs
|
17
|
+
@import "govuk-frontend";
|
18
|
+
|
15
19
|
// Custom
|
16
20
|
@import "base";
|
17
21
|
@import "layout";
|
@@ -25,7 +25,7 @@
|
|
25
25
|
.govuk-form-group--error {
|
26
26
|
box-sizing: border-box;
|
27
27
|
padding-left: $gutter-half - $validation-bdr-size;
|
28
|
-
border-left: $validation-bdr-size-lg solid $error-colour;
|
28
|
+
//border-left: $validation-bdr-size-lg solid $error-colour;
|
29
29
|
|
30
30
|
&:focus {
|
31
31
|
outline: $focus-outline;
|
@@ -42,7 +42,7 @@
|
|
42
42
|
margin-bottom: 0.5em;
|
43
43
|
}
|
44
44
|
@include bold-19;
|
45
|
-
color: $error-colour;
|
45
|
+
//color: $error-colour;
|
46
46
|
}
|
47
47
|
|
48
48
|
.invalid-input,
|
@@ -71,11 +71,20 @@ function formFocus() {
|
|
71
71
|
var labels;
|
72
72
|
var summaries;
|
73
73
|
|
74
|
-
|
74
|
+
var editMode = getElementFromSummaryLink && getEditPath === 'edit';
|
75
|
+
|
76
|
+
if (getElementFromSummaryLink && document.getElementById(getElementFromSummaryLink) && editMode) {
|
75
77
|
document.getElementById(getElementFromSummaryLink).focus();
|
78
|
+
}
|
79
|
+
|
80
|
+
if (getElementFromSummaryLink && document.getElementById(getElementFromSummaryLink + '-group') && editMode) {
|
76
81
|
document.getElementById(getElementFromSummaryLink + '-group').scrollIntoView();
|
77
82
|
}
|
78
83
|
|
84
|
+
if (document.getElementById(getElementFromSummaryLink + '-day') && forms.length === 1 && editMode) {
|
85
|
+
document.getElementById(getElementFromSummaryLink + '-day').focus();
|
86
|
+
}
|
87
|
+
|
79
88
|
if (forms.length > 0) {
|
80
89
|
labels = document.getElementsByTagName('label');
|
81
90
|
if (labels) {
|
@@ -7,12 +7,14 @@ var groupBy = require('lodash').groupBy;
|
|
7
7
|
var helpers = require('./helpers');
|
8
8
|
var inputs; var groups;
|
9
9
|
var toggleAttr = 'data-toggle';
|
10
|
-
var
|
10
|
+
var checkboxHiddenClass = 'govuk-checkboxes__conditional--hidden';
|
11
|
+
var radioHiddenClass = 'govuk-radios__conditional--hidden';
|
11
12
|
|
12
13
|
function inputClicked(e, target) {
|
13
14
|
target = target || helpers.target(e);
|
14
15
|
var shown;
|
15
16
|
each(groups[target.name], function (input) {
|
17
|
+
var hiddenClass = (input.type.match(/checkbox/)) ? checkboxHiddenClass : radioHiddenClass;
|
16
18
|
var id = input.getAttribute('aria-controls');
|
17
19
|
var toggle = document.getElementById(id);
|
18
20
|
if (toggle) {
|
@@ -24,7 +24,12 @@ function clicked(e) {
|
|
24
24
|
}
|
25
25
|
|
26
26
|
if (inputs) {
|
27
|
-
inputs[0].
|
27
|
+
if (inputs[0].getAttribute('type') === 'hidden') {
|
28
|
+
var getVisibleElements = group.querySelectorAll('input[type=text]');
|
29
|
+
getVisibleElements[0].focus();
|
30
|
+
} else {
|
31
|
+
inputs[0].focus();
|
32
|
+
}
|
28
33
|
}
|
29
34
|
}
|
30
35
|
}
|
package/lib/health.js
CHANGED
package/lib/sessions.js
CHANGED
@@ -25,9 +25,11 @@ module.exports = (options, rateLimitType) => {
|
|
25
25
|
}
|
26
26
|
|
27
27
|
const closeConnection = async err => {
|
28
|
-
await redisClient.
|
28
|
+
await redisClient.v4.QUIT();
|
29
29
|
return next(err);
|
30
30
|
};
|
31
|
+
redisClient.on('error', err => logger.log('error', err));
|
32
|
+
await redisClient.connect();
|
31
33
|
|
32
34
|
try {
|
33
35
|
// fetch records of current user using IP address, returns null when no record is found
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "hof",
|
3
3
|
"description": "A bootstrap for HOF projects",
|
4
|
-
"version": "20.0.0-beta.
|
4
|
+
"version": "20.0.0-redis-beta.32-redis-beta",
|
5
5
|
"license": "MIT",
|
6
6
|
"main": "index.js",
|
7
7
|
"author": "HomeOffice",
|
@@ -42,7 +42,7 @@
|
|
42
42
|
"callsite": "^1.0.0",
|
43
43
|
"chalk": "^2.0.0",
|
44
44
|
"chokidar": "^3.4.0",
|
45
|
-
"connect-redis": "^
|
45
|
+
"connect-redis": "^6.1.3",
|
46
46
|
"cookie-parser": "^1.4.6",
|
47
47
|
"cp": "^0.2.0",
|
48
48
|
"csrf": "^3.0.2",
|
@@ -79,7 +79,8 @@
|
|
79
79
|
"nodemailer-ses-transport": "^1.5.0",
|
80
80
|
"nodemailer-smtp-transport": "^2.7.4",
|
81
81
|
"nodemailer-stub-transport": "^1.1.0",
|
82
|
-
"
|
82
|
+
"notifications-node-client": "^5.1.1",
|
83
|
+
"redis": "^4.3.1",
|
83
84
|
"reqres": "^3.0.1",
|
84
85
|
"request": "^2.79.0",
|
85
86
|
"rimraf": "^3.0.2",
|
@@ -30,11 +30,7 @@ module.exports = {
|
|
30
30
|
},
|
31
31
|
'/dob': {
|
32
32
|
fields: ['dateOfBirth'],
|
33
|
-
next: '/address'
|
34
|
-
locals: {
|
35
|
-
step: 'dob',
|
36
|
-
labelClassName: 'govuk-input'
|
37
|
-
}
|
33
|
+
next: '/address'
|
38
34
|
},
|
39
35
|
'/address': {
|
40
36
|
fields: ['building', 'street', 'townOrCity', 'postcode'],
|