hof 20.0.0-beta.9 → 20.0.0-timeout-1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. package/.nyc_output/6ec5c088-e828-4f32-9115-eefea6cdc69b.json +1 -0
  2. package/.nyc_output/processinfo/6ec5c088-e828-4f32-9115-eefea6cdc69b.json +1 -0
  3. package/.nyc_output/processinfo/index.json +1 -1
  4. package/README.md +329 -256
  5. package/components/index.js +2 -1
  6. package/components/notify/index.js +60 -0
  7. package/components/notify/notify.js +25 -0
  8. package/controller/controller.js +14 -4
  9. package/frontend/template-mixins/mixins/template-mixins.js +7 -3
  10. package/frontend/template-mixins/partials/forms/checkbox-group.html +10 -1
  11. package/frontend/template-mixins/partials/forms/input-text-date.html +1 -1
  12. package/frontend/template-mixins/partials/forms/input-text-group.html +5 -3
  13. package/frontend/template-mixins/partials/forms/option-group.html +9 -0
  14. package/frontend/template-mixins/partials/forms/select.html +1 -1
  15. package/frontend/template-mixins/partials/forms/textarea-group.html +2 -2
  16. package/frontend/template-partials/views/layout.html +10 -3
  17. package/frontend/template-partials/views/partials/cookie-banner.html +1 -1
  18. package/frontend/template-partials/views/partials/form.html +2 -1
  19. package/frontend/template-partials/views/partials/head.html +3 -0
  20. package/frontend/template-partials/views/partials/page.html +1 -0
  21. package/frontend/template-partials/views/partials/session-timeout-popup.html +18 -0
  22. package/frontend/template-partials/views/partials/warn.html +7 -0
  23. package/frontend/themes/gov-uk/styles/govuk.scss +4 -0
  24. package/frontend/themes/gov-uk/styles/modules/_validation.scss +2 -2
  25. package/frontend/toolkit/assets/javascript/form-focus.js +10 -1
  26. package/frontend/toolkit/assets/javascript/validation.js +6 -1
  27. package/package.json +2 -1
  28. package/sandbox/apps/sandbox/fields.js +1 -0
  29. package/sandbox/apps/sandbox/index.js +1 -5
  30. package/sandbox/assets/scss/app.scss +0 -52
  31. package/sandbox/package.json +2 -0
  32. package/sandbox/server.js +2 -1
  33. package/sandbox/yarn.lock +39 -564
  34. package/.nyc_output/e2fdc3eb-4fd2-47e0-a392-fe5f665776a4.json +0 -1
  35. package/.nyc_output/processinfo/e2fdc3eb-4fd2-47e0-a392-fe5f665776a4.json +0 -1
  36. package/.vscode/settings.json +0 -6
  37. package/sandbox/.env +0 -1
  38. package/sandbox/apps/sandbox/translations/en/default.json +0 -203
  39. package/sandbox/public/css/app.css +0 -9439
  40. package/sandbox/public/images/icons/icon-caret-left.png +0 -0
  41. package/sandbox/public/images/icons/icon-complete.png +0 -0
  42. package/sandbox/public/images/icons/icon-cross-remove-sign.png +0 -0
  43. package/sandbox/public/js/bundle.js +0 -35644
@@ -5,5 +5,6 @@ module.exports = {
5
5
  clearSession: require('./clear-session'),
6
6
  date: require('./date'),
7
7
  emailer: require('./emailer'),
8
- summary: require('./summary')
8
+ summary: require('./summary'),
9
+ notify: require('./notify')
9
10
  };
@@ -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;
@@ -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
- req.form.errors[key].errorLinkId = key + '-' + field.options[0];
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.controlType === 'date-input') {
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) || 'block-label',
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, isRequired }));
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, isRequired }));
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 govuk-radios__hint">{{optionHint}}</div>{{/optionHint}}
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}} invalid-input{{/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}} invalid-input{{/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-input__prefix" aria-hidden="true">{{suffix}}</div>
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}} invalid-input{{/error}}" name="{{id}}" aria-required="{{required}}">
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}} invalid-input{{/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
- <li class="govuk-footer__inline-list-item"><a class="govuk-footer__link" href="/cookies">{{#t}}base.cookies{{/t}}</a></li>
48
- <li class="govuk-footer__inline-list-item"><a class="govuk-footer__link" href="/accessibility">{{#t}}base.accessibility{{/t}}</a></li>
49
- <li class="govuk-footer__inline-list-item"><a class="govuk-footer__link" href="/terms-and-conditions">{{#t}}base.terms{{/t}}</a></li>
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="/student-help/cookies">change your cookie settings</a> at any time.
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}}<span class="govuk-hint" >{{intro}}</span>{{/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}}" />
@@ -1,2 +1,5 @@
1
1
  <meta name="format-detection" content="telephone=no">
2
2
  <link rel="stylesheet" href="{{assetPath}}/css/app.css">
3
+ <noscript>
4
+ <meta http-equiv="refresh" content="{{sessionTimeOut}};url='/session-timeout'"/>
5
+ </noscript>
@@ -16,6 +16,7 @@
16
16
  {{<partials-form}}
17
17
  {{$form}}
18
18
  {{$page-content}}{{/page-content}}
19
+ {{>partials-session-timeout-popup}}
19
20
  {{/form}}
20
21
  {{/partials-form}}
21
22
  {{/content}}
@@ -0,0 +1,18 @@
1
+ <dialog id="js-modal-dialog" data-session-timeout="{{sessionTimeOut}}" data-session-timeout-warning="{{sessionTimeOutWarning}}"
2
+ data-session-timeout-final-warning="{{finalSessionTimeOutWarning}}" data-url-redirect="/session-timeout" class="modal-dialog dialog" role="dialog"
3
+ aria-live="polite" aria-labelledby="dialog-title" aria-describedby="at-timer">
4
+ <div class="modal-dialog__inner">
5
+ <h1 id="dialog-title" class="govuk-heading-l">
6
+ Your application will time out soon
7
+ </h1>
8
+ <div class="modal-dialog__inner__text">
9
+ <div id="timer" class="timer" aria-hidden="true" aria-relevant="additions"></div>
10
+ <div id="at-timer" class="at-timer govuk-visually-hidden" role="status"></div>
11
+ </div>
12
+ <div class="modal-dialog__inner__block">
13
+ <button class="govuk-button dialog-button modal-dialog__inner__button js-dialog-close" id="timeout-continue-button">Continue application</button>
14
+ </div>
15
+ </div>
16
+ </dialog>
17
+
18
+
@@ -0,0 +1,7 @@
1
+ <div class="govuk-warning-text">
2
+ <span class="govuk-warning-text__icon" aria-hidden="true">!</span>
3
+ <strong class="govuk-warning-text__text">
4
+ <span class="govuk-warning-text__assistive">Warning</span>
5
+ {{warning}}
6
+ </strong>
7
+ </div>
@@ -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
- if (getElementFromSummaryLink && getEditPath === 'edit') {
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) {
@@ -24,7 +24,12 @@ function clicked(e) {
24
24
  }
25
25
 
26
26
  if (inputs) {
27
- inputs[0].focus();
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/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.9",
4
+ "version": "20.0.0-timeout-1",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
7
7
  "author": "HomeOffice",
@@ -79,6 +79,7 @@
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
+ "notifications-node-client": "^5.1.1",
82
83
  "redis": "^3.1.2",
83
84
  "reqres": "^3.0.1",
84
85
  "request": "^2.79.0",
@@ -21,6 +21,7 @@ module.exports = {
21
21
  isPageHeading: 'true'
22
22
  },
23
23
  'dateOfBirth': dateComponent('dateOfBirth', {
24
+ mixin: 'input-date',
24
25
  isPageHeading: 'true',
25
26
  validate: [
26
27
  'required',
@@ -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'],
@@ -1,6 +1,5 @@
1
1
 
2
2
  @import "../../../frontend/themes/gov-uk/styles/govuk";
3
- @import "../../../node_modules/govuk-frontend/govuk/all";
4
3
 
5
4
  //autocomplete styling
6
5
  .tt-menu {
@@ -26,54 +25,3 @@
26
25
  .twitter-typeahead {
27
26
  width: 100%;
28
27
  }
29
-
30
- // govuk cookie banner styling
31
- .govuk-banner--success {
32
- border-color: #00703c;
33
- color: #00703c;
34
- }
35
-
36
- .govuk-banner {
37
- border: 5px solid #1d70b8;
38
- font-size: 0;
39
- margin-bottom: 30px;
40
- padding: 10px;
41
- }
42
-
43
- .govuk-banner__icon{
44
- display: inline-block;
45
- }
46
-
47
- .govuk-banner__message {
48
- font-family: "GDS Transport", Arial, sans-serif;
49
- -webkit-font-smoothing: antialiased;
50
- font-weight: 400;
51
- font-size: 1rem;
52
- line-height: 1.25;
53
- color: #0b0c0c;
54
- display: block;
55
- overflow: hidden;
56
- display: inline-block;
57
- margin-left: 10px;
58
- }
59
-
60
- .govuk-banner__assistive {
61
- position: absolute !important;
62
- width: 1px !important;
63
- height: 1px !important;
64
- margin: 0 !important;
65
- padding: 0 !important;
66
- overflow: hidden !important;
67
- clip: rect(0 0 0 0) !important;
68
- clip-path: inset(50%) !important;
69
- border: 0 !important;
70
- white-space: nowrap !important;
71
- }
72
-
73
- .cookie-table-holder > table > tbody > tr > td:first-child{
74
- font-weight:bold;
75
- }
76
-
77
- .js-enabled #global-cookie-message {
78
- display: none;
79
- }
@@ -15,7 +15,9 @@
15
15
  },
16
16
  "author": "",
17
17
  "dependencies": {
18
+ "govuk-frontend": "3.14",
18
19
  "jquery": "^3.6.0",
20
+ "sass": "^1.53.0",
19
21
  "typeahead-aria": "^1.0.4"
20
22
  },
21
23
  "devDependencies": {
package/sandbox/server.js CHANGED
@@ -13,5 +13,6 @@ bootstrap({
13
13
  active: true
14
14
  }
15
15
  },
16
- getAccessibility: true
16
+ getAccessibility: true,
17
+ "port": 8082
17
18
  });