hof 22.1.0-timeout-warning-sign-in-beta.3 → 22.2.0-time-mixin-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/.github/workflows/automate-publish.yml +4 -4
  2. package/.github/workflows/automate-tag.yml +16 -16
  3. package/.nyc_output/34671fe1-441d-41ed-b012-ece4e3964dbb.json +1 -0
  4. package/.nyc_output/processinfo/34671fe1-441d-41ed-b012-ece4e3964dbb.json +1 -0
  5. package/.nyc_output/processinfo/index.json +1 -1
  6. package/CHANGELOG.md +20 -19
  7. package/README.md +44 -7
  8. package/components/emailer/transports/smtp.js +1 -1
  9. package/components/index.js +1 -0
  10. package/components/session-timeout-warning/index.js +11 -0
  11. package/components/time/fields.js +12 -0
  12. package/components/time/index.js +168 -0
  13. package/components/time/templates/time.html +20 -0
  14. package/config/hof-defaults.js +2 -0
  15. package/controller/controller.js +9 -0
  16. package/controller/validation/validators.js +13 -0
  17. package/frontend/template-mixins/mixins/template-mixins.js +45 -1
  18. package/frontend/template-mixins/partials/forms/input-text-time.html +37 -0
  19. package/frontend/template-partials/translations/src/en/save-and-exit.json +4 -0
  20. package/frontend/template-partials/views/partials/head.html +4 -1
  21. package/frontend/template-partials/views/partials/session-timeout-warning.html +7 -6
  22. package/frontend/template-partials/views/save-and-exit.html +1 -3
  23. package/frontend/themes/gov-uk/styles/_time-input.scss +5 -0
  24. package/frontend/themes/gov-uk/styles/govuk.scss +1 -0
  25. package/frontend/toolkit/assets/javascript/form-focus.js +4 -0
  26. package/index.js +3 -0
  27. package/lib/deindex.js +18 -0
  28. package/lib/router.js +2 -0
  29. package/package.json +1 -2
  30. package/{pull-request-template.md → pull_request_template.md} +1 -1
  31. package/sandbox/.env +2 -2
  32. package/sandbox/apps/sandbox/fields.js +9 -0
  33. package/sandbox/apps/sandbox/index.js +4 -0
  34. package/sandbox/apps/sandbox/sections/summary-data-sections.js +7 -0
  35. package/sandbox/apps/sandbox/translations/en/default.json +12 -2
  36. package/sandbox/apps/sandbox/translations/src/en/fields.json +4 -0
  37. package/sandbox/apps/sandbox/translations/src/en/pages.json +5 -2
  38. package/sandbox/apps/sandbox/translations/src/en/validation.json +3 -0
  39. package/sandbox/apps/sandbox/views/save-and-exit.html +19 -0
  40. package/sandbox/public/css/app.css +40 -34
  41. package/sandbox/public/js/bundle.js +4 -0
  42. package/utilities/autofill/inputs.js +6 -1
  43. package/wizard/index.js +2 -0
  44. package/.nyc_output/9376679c-295d-4483-8c62-60e08528311a.json +0 -1
  45. package/.nyc_output/processinfo/9376679c-295d-4483-8c62-60e08528311a.json +0 -1
@@ -13,6 +13,7 @@ const PANELMIXIN = 'partials/mixins/panel';
13
13
  const PARTIALS = [
14
14
  'partials/forms/input-text-group',
15
15
  'partials/forms/input-text-date',
16
+ 'partials/forms/input-text-time',
16
17
  'partials/forms/input-submit',
17
18
  'partials/forms/select',
18
19
  'partials/forms/checkbox',
@@ -213,6 +214,7 @@ module.exports = function (options) {
213
214
  label: t(lKey),
214
215
  labelClassName: labelClassName ? `govuk-label ${labelClassName}` : 'govuk-label',
215
216
  formGroupClassName: classNames(field, 'formGroupClassName') || extension.formGroupClassName || 'govuk-form-group',
217
+ timeInputItemClassName: 'time-input__item',
216
218
  hint: hint,
217
219
  hintId: extension.hintId || (hint ? key + '-hint' : null),
218
220
  error: this.errors && this.errors[key],
@@ -221,11 +223,12 @@ module.exports = function (options) {
221
223
  required: required,
222
224
  pattern: extension.pattern,
223
225
  date: extension.date,
226
+ time: extension.time,
224
227
  autocomplete: autocomplete,
225
228
  child: field.child,
226
229
  isPageHeading: field.isPageHeading,
227
230
  attributes: field.attributes,
228
- isPrefixOrSuffix: _.map(field.attributes, item => {if (item.prefix || item.suffix !== undefined) return true;}),
231
+ isPrefixOrSuffix: _.map(field.attributes, item => { if (item.prefix || item.suffix !== undefined) return true; }),
229
232
  isMaxlengthOrMaxword: maxlength(field) || extension.maxlength || maxword(field) || extension.maxword,
230
233
  renderChild: renderChild.bind(this)
231
234
  });
@@ -468,6 +471,47 @@ module.exports = function (options) {
468
471
  return parts.concat(monthPart, yearPart).join('\n');
469
472
  };
470
473
  }
474
+ },
475
+ 'input-time': {
476
+ handler: function () {
477
+ /**
478
+ * props: '[value] [id]'
479
+ */
480
+ return function (key) {
481
+ const field = Object.assign({}, this.options.fields[key] || options.fields[key]);
482
+ key = hoganRender(key, this);
483
+ // Exact unless there is a inexact property against the fields key.
484
+ const isExact = field.inexact !== true;
485
+
486
+ let autocomplete = field.autocomplete || {};
487
+ if (autocomplete === 'off') {
488
+ autocomplete = {
489
+ hour: 'off',
490
+ minute: 'off'
491
+ };
492
+ } else if (typeof autocomplete === 'string') {
493
+ autocomplete = {
494
+ hour: autocomplete + '-hour',
495
+ minute: autocomplete + '-minute'
496
+ };
497
+ }
498
+ const isThisRequired = field.validate ? field.validate.indexOf('required') > -1 : false;
499
+ const formGroupClassName = (field.formGroup && field.formGroup.className) ? field.formGroup.className : '';
500
+ const classNameHour = (field.controlsClass && field.controlsClass.hour) ? field.controlsClass.hour : 'govuk-input--width-2';
501
+ const classNameMinute = (field.controlsClass && field.controlsClass.minute) ? field.controlsClass.minute : 'govuk-input--width-2';
502
+
503
+ const parts = [];
504
+
505
+ if (isExact) {
506
+ const hourPart = compiled['partials/forms/input-text-time'].render(inputText.call(this, key + '-hour', { pattern: '[0-9]*', min: 1, max: 24, maxlength: 2, hintId: key + '-hint', time: true, autocomplete: autocomplete.hour, formGroupClassName, className: classNameHour, isThisRequired }));
507
+ parts.push(hourPart);
508
+ }
509
+
510
+ const minutePart = compiled['partials/forms/input-text-time'].render(inputText.call(this, key + '-minute', { pattern: '[0-9]*', min: 0, max: 59, maxlength: 2, hintId: key + '-hint', time: true, autocomplete: autocomplete.minute, formGroupClassName, className: classNameMinute, isThisRequired }));
511
+
512
+ return parts.concat(minutePart).join('\n');
513
+ };
514
+ }
471
515
  }
472
516
  };
473
517
 
@@ -0,0 +1,37 @@
1
+ <div class="{{timeInputItemClassName}}">
2
+ <div id="{{id}}-group" class="{{#formGroupClassName}} {{formGroupClassName}}{{/formGroupClassName}}">
3
+ <label for="{{id}}" class="{{labelClassName}}">
4
+ <span class="label-text">{{{label}}}</span>
5
+ </label>
6
+ {{#hint}}<span {{$hintId}}id="{{hintId}}" {{/hintId}}class="govuk-hint">{{hint}}</span>{{/hint}}
7
+ {{#renderChild}}{{/renderChild}}
8
+ {{#attributes}}
9
+ {{#prefix}}
10
+ <div class="govuk-input__prefix" aria-hidden="true">{{prefix}}</div>
11
+ {{/prefix}}
12
+ {{/attributes}}
13
+ <input
14
+ type="{{type}}"
15
+ name="{{id}}"
16
+ id="{{id}}"
17
+ class="govuk-input{{#className}} {{className}}{{/className}}{{#error}} govuk-input--error{{/error}}"
18
+ aria-required="{{required}}"
19
+ {{#value}} value="{{value}}"{{/value}}
20
+ {{#min}} min="{{min}}"{{/min}}
21
+ {{#max}} max="{{max}}"{{/max}}
22
+ {{#maxlength}} maxlength="{{maxlength}}"{{/maxlength}}
23
+ {{#pattern}} pattern="{{pattern}}"{{/pattern}}
24
+ {{#hintId}} aria-describedby="{{hintId}}"{{/hintId}}
25
+ {{#error}} aria-invalid="true"{{/error}}
26
+ {{#autocomplete}} autocomplete="{{autocomplete}}"{{/autocomplete}}
27
+ {{#attributes}}
28
+ {{attribute}}="{{value}}"
29
+ {{/attributes}}
30
+ >
31
+ {{#attributes}}
32
+ {{#suffix}}
33
+ <div class="govuk-input__prefix" aria-hidden="true">{{suffix}}</div>
34
+ {{/suffix}}
35
+ {{/attributes}}
36
+ </div>
37
+ </div>
@@ -0,0 +1,4 @@
1
+ {
2
+ "header": "You have been signed out",
3
+ "message": "Any answers you saved have not been affected. You can sign back in to your application by returning to the <a href='/' class='govuk-link'>start page</a>."
4
+ }
@@ -21,8 +21,11 @@
21
21
  {{/cookiesAccepted}}
22
22
  {{/gtmTagId}}
23
23
 
24
+ {{#deIndex}}
25
+ <meta name="robots" content="noindex">
26
+ {{/deIndex}}
24
27
  <meta name="format-detection" content="telephone=no">
25
28
  <noscript>
26
- <meta http-equiv="refresh" content="{{sessionTimeOut}};url='/session-timeout'"/>
29
+ <meta http-equiv="refresh" content="{{sessionTimeOut}};url='{{baseUrl}}/session-timeout'"/>
27
30
  </noscript>
28
31
  <link rel="stylesheet" href="{{assetPath}}/css/app.css">
@@ -8,7 +8,7 @@
8
8
  data-url-redirect="/session-timeout" class="modal-dialog dialog" role="dialog"
9
9
  aria-live="polite" aria-labelledby="dialog-title" aria-describedby="at-timer">
10
10
  <div class="modal-dialog__inner">
11
- {{^showSaveAndExit}}
11
+ {{^showSaveAndExit}}
12
12
  <h2 id="dialog-title" class="govuk-heading-l">
13
13
  {{#dialogTitle}}{{#t}}pages.session-timeout-warning.dialog-title{{/t}}{{/dialogTitle}}{{^dialogTitle}}Your page will time out soon{{/dialogTitle}}
14
14
  </h2>
@@ -19,9 +19,9 @@ data-url-redirect="/session-timeout" class="modal-dialog dialog" role="dialog"
19
19
  <p class="dialog-text visually-hidden">{{#dialogText}}{{#t}}pages.session-timeout-warning.dialog-text{{/t}}{{/dialogText}}{{^dialogText}}If that happens, your progress will not be saved.{{/dialogText}}</p>
20
20
  </div>
21
21
  <button class="govuk-button dialog-button js-dialog-close" id="timeout-continue-button" data-module="govuk-button">{{#timeoutContinueButton}}{{#t}}pages.session-timeout-warning.timeout-continue-button{{/t}}{{/timeoutContinueButton}}{{^timeoutContinueButton}}Stay on this page{{/timeoutContinueButton}}</button>
22
- <a href="/exit" class="govuk-link dialog-exit-link" role="button">{{#dialogExitLink}}{{#t}}pages.session-timeout-warning.dialog-exit-link{{/t}}{{/dialogExitLink}}{{^dialogExitLink}}Exit this form{{/dialogExitLink}}</a>
23
- {{/showSaveAndExit}}
24
- {{#showSaveAndExit}}
22
+ <a href="{{baseUrl}}{{exitStep}}" class="govuk-link dialog-exit-link" role="button">{{#dialogExitLink}}{{#t}}pages.session-timeout-warning.dialog-exit-link{{/t}}{{/dialogExitLink}}{{^dialogExitLink}}Exit this form{{/dialogExitLink}}</a>
23
+ {{/showSaveAndExit}}
24
+ {{#showSaveAndExit}}
25
25
  <h2 id="dialog-title" class="govuk-heading-l">
26
26
  {{#dialogTitle}}{{#t}}pages.session-timeout-warning.dialog-title{{/t}}{{/dialogTitle}}{{^dialogTitle}}You will be signed out soon{{/dialogTitle}}
27
27
  </h2>
@@ -29,9 +29,10 @@ data-url-redirect="/session-timeout" class="modal-dialog dialog" role="dialog"
29
29
  <div id="timer" class="timer" aria-hidden="true" aria-relevant="additions"></div>
30
30
  <div id="at-timer" class="at-timer govuk-visually-hidden" role="status"></div>
31
31
  <p class="dialog-text-prefix visually-hidden">To protect your information, you will be signed out in </p>
32
+ <p class="dialog-text visually-hidden">{{#dialogText}}{{#t}}pages.session-timeout-warning.dialog-text{{/t}}{{/dialogText}}{{^dialogText}}Any answers you have saved will not be affected, but your progress on this page will not be saved.{{/dialogText}}</p>
32
33
  </div>
33
34
  <button class="govuk-button dialog-button js-dialog-close" id="timeout-continue-button" data-module="govuk-button">{{#timeoutContinueButton}}{{#t}}pages.session-timeout-warning.timeout-continue-button{{/t}}{{/timeoutContinueButton}}{{^timeoutContinueButton}}Stay signed in{{/timeoutContinueButton}}</button>
34
- <a href="{{baseUrl}}/save-and-exit" class="govuk-link dialog-exit-link" role="button">{{#dialogExitLink}}{{#t}}pages.session-timeout-warning.dialog-exit-link{{/t}}{{/dialogExitLink}}{{^dialogExitLink}}Sign out{{/dialogExitLink}}</a>
35
- {{/showSaveAndExit}}
35
+ <a href="{{baseUrl}}{{saveAndExitStep}}" class="govuk-link dialog-exit-link" role="button">{{#dialogExitLink}}{{#t}}pages.session-timeout-warning.dialog-exit-link{{/t}}{{/dialogExitLink}}{{^dialogExitLink}}Sign out{{/dialogExitLink}}</a>
36
+ {{/showSaveAndExit}}
36
37
  </div>
37
38
  </dialog>
@@ -12,8 +12,6 @@
12
12
  {{/header}}
13
13
 
14
14
  {{$content}}
15
- <p>{{#t}}pages.save-and-exit.paragraph-1{{/t}}</p>
16
- <p>{{#t}}pages.save-and-exit.paragraph-2{{/t}}</p>
17
- <p>{{#t}}pages.save-and-exit.paragraph-3{{/t}} <a href="/" class="govuk-link">start page.</a></p>
15
+ <p>{{#saveExitFormContent}}{{#t}}pages.save-and-exit.message{{/t}}{{/saveExitFormContent}}{{^saveExitFormContent}}{{{message}}}{{/saveExitFormContent}}</p>
18
16
  {{/content}}
19
17
  {{/layout}}
@@ -0,0 +1,5 @@
1
+ .time-input__item {
2
+ display: inline-block;
3
+ margin-right: 20px;
4
+ margin-bottom: 0;
5
+ }
@@ -27,6 +27,7 @@ $path: "/public/images/" !default;
27
27
  @import "check_your_answers";
28
28
  @import "pdf";
29
29
  @import "session-timeout-dialog";
30
+ @import "time-input";
30
31
 
31
32
  // Modules
32
33
  @import "modules/validation";
@@ -85,6 +85,10 @@ function formFocus() {
85
85
  document.getElementById(getElementFromSummaryLink + '-day').focus();
86
86
  }
87
87
 
88
+ if (document.getElementById(getElementFromSummaryLink + '-hour') && forms.length === 1 && editMode) {
89
+ document.getElementById(getElementFromSummaryLink + '-hour').focus();
90
+ }
91
+
88
92
  if (forms.length > 0) {
89
93
  labels = document.getElementsByTagName('label');
90
94
  if (labels) {
package/index.js CHANGED
@@ -14,6 +14,7 @@ const router = require('./lib/router');
14
14
  const health = require('./lib/health');
15
15
  const serveStatic = require('./lib/serve-static');
16
16
  const gaTagSetup = require('./lib/ga-tag');
17
+ const deIndexer = require('./lib/deindex');
17
18
  const sessionStore = require('./lib/sessions');
18
19
  const settings = require('./lib/settings');
19
20
  const defaults = require('./config/hof-defaults');
@@ -153,6 +154,7 @@ function bootstrap(options) {
153
154
  res.locals.sessionTimeOutWarning = config.sessionTimeOutWarning;
154
155
  res.locals.sessionTimeoutWarningContent = config.sessionTimeoutWarningContent;
155
156
  res.locals.exitFormContent = config.exitFormContent;
157
+ res.locals.saveExitFormContent = config.saveExitFormContent;
156
158
  next();
157
159
  });
158
160
 
@@ -204,6 +206,7 @@ function bootstrap(options) {
204
206
  serveStatic(app, config);
205
207
  settings(app, config);
206
208
  gaTagSetup(app, config);
209
+ deIndexer(app, config);
207
210
 
208
211
  const sessions = sessionStore(app, config);
209
212
  app.use('/healthz', health(sessions));
package/lib/deindex.js ADDED
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ module.exports = (app, config) => {
4
+ // Ensure the value of deIndex is evaluated as a boolean regardless of if single quotes are used
5
+ // to have the expected conditional behaviour in the Mustache template
6
+ const deIndex = (config.deIndexForm === 'true' || config.deIndexForm === true);
7
+
8
+ app.use((req, res, next) => {
9
+ // Preparing common res.locals properties
10
+ const properties = {
11
+ deIndex: deIndex
12
+ };
13
+ res.locals = Object.assign(res.locals, properties);
14
+ next();
15
+ });
16
+
17
+ return app;
18
+ };
package/lib/router.js CHANGED
@@ -30,6 +30,8 @@ function getWizardConfig(config) {
30
30
  // whitelist properties from the route's config that should be passed into the form wizard
31
31
  const props = [
32
32
  'confirmStep',
33
+ 'exitStep',
34
+ 'saveAndExitStep',
33
35
  'params'
34
36
  ];
35
37
  Object.assign(wizardConfig, _.pick(config.route, props));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hof",
3
3
  "description": "A bootstrap for HOF projects",
4
- "version": "22.1.0-timeout-warning-sign-in-beta.3",
4
+ "version": "22.2.0-time-mixin-beta",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
7
7
  "author": "HomeOffice",
@@ -79,7 +79,6 @@
79
79
  "mustache": "^4.2.0",
80
80
  "nodemailer": "^6.6.3",
81
81
  "nodemailer-ses-transport": "^1.5.1",
82
- "nodemailer-smtp-transport": "^2.7.4",
83
82
  "nodemailer-stub-transport": "^1.1.0",
84
83
  "notifications-node-client": "^8.2.0",
85
84
  "redis": "^3.1.2",
@@ -12,5 +12,5 @@
12
12
  - [ ] I have created a JIRA number for my commit
13
13
  - [ ] I have followed the chris beams method for my commit https://cbea.ms/git-commit/
14
14
  here is an [example commit](https://github.com/UKHomeOfficeForms/hof/commit/810959f391187c7c4af6db262bcd143b50093a6e)
15
- - [ ] Ensure drone builds are green especially tests
15
+ - [ ] Ensure workflow jobs are passing especially tests
16
16
  - [ ] I will squash the commits before merging
package/sandbox/.env CHANGED
@@ -1,3 +1,3 @@
1
- SESSION_TTL=65
2
- SESSION_TIMEOUT_WARNING=60
1
+ # SESSION_TTL=10
2
+ # SESSION_TIMEOUT_WARNING=5
3
3
  NODE_ENV = 'local
@@ -3,6 +3,7 @@
3
3
 
4
4
  const dateComponent = require('../../../').components.date;
5
5
  const staticAppealStages = require('./lib/staticAppealStages');
6
+ const timeComponent = require('../../../').components.time;
6
7
 
7
8
  module.exports = {
8
9
  'landing-page-radio': {
@@ -26,6 +27,14 @@ module.exports = {
26
27
  { type: 'after', arguments: ['1900'] }
27
28
  ]
28
29
  }),
30
+ time: timeComponent('time', {
31
+ mixin: 'input-time',
32
+ isPageHeading: 'true',
33
+ validate: [
34
+ 'required',
35
+ 'time'
36
+ ]
37
+ }),
29
38
  building: {
30
39
  validate: ['required', 'notUrl', { type: 'maxlength', arguments: 100 }]
31
40
  },
@@ -31,6 +31,10 @@ module.exports = {
31
31
  '/dob': {
32
32
  fields: ['dateOfBirth'],
33
33
  locals: { showSaveAndExit: true },
34
+ next: '/time'
35
+ },
36
+ '/time': {
37
+ fields: ['time'],
34
38
  next: '/address'
35
39
  },
36
40
  '/address': {
@@ -1,5 +1,6 @@
1
1
  const moment = require('moment');
2
2
  const PRETTY_DATE_FORMAT = 'Do MMMM YYYY';
3
+ const PRETTY_TIME_FORMAT = 'k:mma';
3
4
  const APPEAL_STAGES = require('../lib/staticAppealStages').getstaticAppealStages();
4
5
  const _ = require('lodash');
5
6
 
@@ -11,6 +12,12 @@ module.exports = {
11
12
  parse: d => d && moment(d).format(PRETTY_DATE_FORMAT)
12
13
  }
13
14
  ],
15
+ time: [
16
+ {
17
+ field: 'time',
18
+ parse: t => t && moment(t, 'kk:mm').format(PRETTY_TIME_FORMAT)
19
+ }
20
+ ],
14
21
  address: [
15
22
  'building',
16
23
  'street',
@@ -26,6 +26,10 @@
26
26
  "legend": "What is your date of birth?",
27
27
  "hint": "For example, 31 10 1990"
28
28
  },
29
+ "time": {
30
+ "legend": "What is the current time?",
31
+ "hint": "For example, 12 40 "
32
+ },
29
33
  "building": {
30
34
  "label": "Building and street"
31
35
  },
@@ -137,6 +141,9 @@
137
141
  "applicantsDetails": {
138
142
  "header": "Applicant's details"
139
143
  },
144
+ "time": {
145
+ "header": "Time"
146
+ },
140
147
  "address": {
141
148
  "header": "Address"
142
149
  },
@@ -177,9 +184,9 @@
177
184
  },
178
185
  "save-and-exit": {
179
186
  "header": "You have been signed out",
180
- "paragraph-1": "Your form doesnt appear to have been worked on for 30 minutes so we closed it for security.",
187
+ "paragraph-1": "Your form doesn't appear to have been worked on for 30 minutes so we closed it for security.",
181
188
  "paragraph-2": "Any answers you saved have not been affected.",
182
- "paragraph-3": "You can sign back in to your application at any time by returning to the"
189
+ "paragraph-3": "You can sign back in to your application at any time by returning to the <a href='/' class='govuk-link'>start page</a>."
183
190
  }
184
191
  },
185
192
  "validation": {
@@ -194,6 +201,9 @@
194
201
  "after": "Enter a date after 1 1 1900",
195
202
  "before": "Enter a date that is in the past"
196
203
  },
204
+ "time": {
205
+ "default": "Enter a time in the correct format; for example, 12 40"
206
+ },
197
207
  "building": {
198
208
  "default": "Enter details of your building and street"
199
209
  },
@@ -21,6 +21,10 @@
21
21
  "legend": "What is your date of birth?",
22
22
  "hint": "For example, 31 10 1990"
23
23
  },
24
+ "time": {
25
+ "legend": "What is the current time?",
26
+ "hint": "For example, 12 40 "
27
+ },
24
28
  "building": {
25
29
  "label": "Building and street"
26
30
  },
@@ -25,6 +25,9 @@
25
25
  "applicantsDetails": {
26
26
  "header": "Applicant's details"
27
27
  },
28
+ "time": {
29
+ "header": "Time"
30
+ },
28
31
  "address": {
29
32
  "header": "Address"
30
33
  },
@@ -65,8 +68,8 @@
65
68
  },
66
69
  "save-and-exit": {
67
70
  "header": "You have been signed out",
68
- "paragraph-1": "Your form doesnt appear to have been worked on for 30 minutes so we closed it for security.",
71
+ "paragraph-1": "Your form doesn't appear to have been worked on for 30 minutes so we closed it for security.",
69
72
  "paragraph-2": "Any answers you saved have not been affected.",
70
- "paragraph-3": "You can sign back in to your application at any time by returning to the"
73
+ "paragraph-3": "You can sign back in to your application at any time by returning to the <a href='/' class='govuk-link'>start page</a>."
71
74
  }
72
75
  }
@@ -10,6 +10,9 @@
10
10
  "after": "Enter a date after 1 1 1900",
11
11
  "before": "Enter a date that is in the past"
12
12
  },
13
+ "time": {
14
+ "default": "Enter a time in the correct format; for example, 12 40"
15
+ },
13
16
  "building": {
14
17
  "default": "Enter details of your building and street"
15
18
  },
@@ -0,0 +1,19 @@
1
+ {{<layout}}
2
+ {{$journeyHeader}}
3
+ {{#t}}journey.header{{/t}}
4
+ {{/journeyHeader}}
5
+
6
+ {{$propositionHeader}}
7
+ {{> partials-navigation}}
8
+ {{/propositionHeader}}
9
+
10
+ {{$header}}
11
+ {{header}}
12
+ {{/header}}
13
+
14
+ {{$content}}
15
+ <p>{{#t}}pages.save-and-exit.paragraph-1{{/t}}</p>
16
+ <p>{{#t}}pages.save-and-exit.paragraph-2{{/t}}</p>
17
+ <p>{{#t}}pages.save-and-exit.paragraph-3{{/t}}</p>
18
+ {{/content}}
19
+ {{/layout}}
@@ -797,9 +797,9 @@ hr {
797
797
  outline: 1px solid transparent;
798
798
  outline-offset: -1px;
799
799
  -webkit-appearance: none;
800
- -webkit-box-shadow: 0 2px 0 #003618;
801
- -moz-box-shadow: 0 2px 0 #003618;
802
- box-shadow: 0 2px 0 #003618;
800
+ -webkit-box-shadow: 0 2px 0 rgb(0, 53.5, 24.2807692308);
801
+ -moz-box-shadow: 0 2px 0 rgb(0, 53.5, 24.2807692308);
802
+ box-shadow: 0 2px 0 rgb(0, 53.5, 24.2807692308);
803
803
  font-size: 1em;
804
804
  line-height: 1.25;
805
805
  text-decoration: none;
@@ -815,7 +815,7 @@ hr {
815
815
  background-color: #00823b;
816
816
  }
817
817
  .button:hover, .button:focus {
818
- background-color: #00692f;
818
+ background-color: rgb(0, 104.5, 47.4269230769);
819
819
  }
820
820
  .button:active {
821
821
  top: 2px;
@@ -834,9 +834,9 @@ hr {
834
834
  }
835
835
  .button.disabled:active, .button[disabled=disabled]:active, .button[disabled]:active {
836
836
  top: 0;
837
- -webkit-box-shadow: 0 2px 0 #003618;
838
- -moz-box-shadow: 0 2px 0 #003618;
839
- box-shadow: 0 2px 0 #003618;
837
+ -webkit-box-shadow: 0 2px 0 rgb(0, 53.5, 24.2807692308);
838
+ -moz-box-shadow: 0 2px 0 rgb(0, 53.5, 24.2807692308);
839
+ box-shadow: 0 2px 0 rgb(0, 53.5, 24.2807692308);
840
840
  }
841
841
  .button:link, .button:link:focus, .button:hover, .button:focus, .button:visited {
842
842
  color: #fff;
@@ -3630,7 +3630,7 @@ input[type=number] {
3630
3630
  border-radius: 0;
3631
3631
  color: #ffffff;
3632
3632
  background-color: #00703c;
3633
- box-shadow: 0 2px 0 #002d18;
3633
+ box-shadow: 0 2px 0 rgb(0, 44.8, 24);
3634
3634
  text-align: center;
3635
3635
  vertical-align: top;
3636
3636
  cursor: pointer;
@@ -3673,7 +3673,7 @@ input[type=number] {
3673
3673
  border: 0;
3674
3674
  }
3675
3675
  .govuk-button:hover {
3676
- background-color: #005a30;
3676
+ background-color: rgb(0, 89.6, 48);
3677
3677
  }
3678
3678
  .govuk-button:active {
3679
3679
  top: 2px;
@@ -3718,18 +3718,18 @@ input[type=number] {
3718
3718
  .govuk-button[disabled=disabled]:active,
3719
3719
  .govuk-button[disabled]:active {
3720
3720
  top: 0;
3721
- box-shadow: 0 2px 0 #002d18;
3721
+ box-shadow: 0 2px 0 rgb(0, 44.8, 24);
3722
3722
  }
3723
3723
 
3724
3724
  .govuk-button--secondary {
3725
3725
  background-color: #f3f2f1;
3726
- box-shadow: 0 2px 0 #929191;
3726
+ box-shadow: 0 2px 0 rgb(145.8, 145.2, 144.6);
3727
3727
  }
3728
3728
  .govuk-button--secondary, .govuk-button--secondary:link, .govuk-button--secondary:visited, .govuk-button--secondary:active, .govuk-button--secondary:hover {
3729
3729
  color: #0b0c0c;
3730
3730
  }
3731
3731
  .govuk-button--secondary:hover {
3732
- background-color: #dbdad9;
3732
+ background-color: rgb(218.7, 217.8, 216.9);
3733
3733
  }
3734
3734
  .govuk-button--secondary:hover[disabled] {
3735
3735
  background-color: #f3f2f1;
@@ -3737,13 +3737,13 @@ input[type=number] {
3737
3737
 
3738
3738
  .govuk-button--warning {
3739
3739
  background-color: #d4351c;
3740
- box-shadow: 0 2px 0 #55150b;
3740
+ box-shadow: 0 2px 0 rgb(84.8, 21.2, 11.2);
3741
3741
  }
3742
3742
  .govuk-button--warning, .govuk-button--warning:link, .govuk-button--warning:visited, .govuk-button--warning:active, .govuk-button--warning:hover {
3743
3743
  color: #ffffff;
3744
3744
  }
3745
3745
  .govuk-button--warning:hover {
3746
- background-color: #aa2a16;
3746
+ background-color: rgb(169.6, 42.4, 22.4);
3747
3747
  }
3748
3748
  .govuk-button--warning:hover[disabled] {
3749
3749
  background-color: #d4351c;
@@ -5221,7 +5221,7 @@ input[type=number] {
5221
5221
  color: #d4351c;
5222
5222
  }
5223
5223
  .govuk-error-summary__list a:hover {
5224
- color: #942514;
5224
+ color: rgb(148.4, 37.1, 19.6);
5225
5225
  }
5226
5226
  .govuk-error-summary__list a:active {
5227
5227
  color: #d4351c;
@@ -6218,7 +6218,7 @@ input[type=number] {
6218
6218
  color: #00703c;
6219
6219
  }
6220
6220
  .govuk-notification-banner--success .govuk-notification-banner__link:hover {
6221
- color: #004e2a;
6221
+ color: rgb(0, 78.4, 42);
6222
6222
  }
6223
6223
  .govuk-notification-banner--success .govuk-notification-banner__link:active {
6224
6224
  color: #00703c;
@@ -6386,48 +6386,48 @@ input[type=number] {
6386
6386
  }
6387
6387
 
6388
6388
  .govuk-tag--grey {
6389
- color: #383f43;
6390
- background: #eeefef;
6389
+ color: rgb(56, 63, 66.5);
6390
+ background: rgb(237.5, 238.5, 239);
6391
6391
  }
6392
6392
 
6393
6393
  .govuk-tag--purple {
6394
- color: #3d2375;
6395
- background: #dbd5e9;
6394
+ color: rgb(60.8, 35.2, 116.8);
6395
+ background: rgb(219.2, 212.8, 233.2);
6396
6396
  }
6397
6397
 
6398
6398
  .govuk-tag--turquoise {
6399
- color: #10403c;
6400
- background: #bfe3e0;
6399
+ color: rgb(16, 64.4, 60.4);
6400
+ background: rgb(190.5, 226.8, 223.8);
6401
6401
  }
6402
6402
 
6403
6403
  .govuk-tag--blue {
6404
- color: #144e81;
6405
- background: #d2e2f1;
6404
+ color: rgb(20.3, 78.4, 128.8);
6405
+ background: rgb(209.8, 226.4, 240.8);
6406
6406
  }
6407
6407
 
6408
6408
  .govuk-tag--yellow {
6409
- color: #594d00;
6410
- background: #fff7bf;
6409
+ color: rgb(89.25, 77.35, 0);
6410
+ background: rgb(255, 246.5, 191.25);
6411
6411
  }
6412
6412
 
6413
6413
  .govuk-tag--orange {
6414
- color: #6e3619;
6415
- background: #fcd6c3;
6414
+ color: rgb(109.8, 53.55, 25.2);
6415
+ background: rgb(251.7, 214.2, 195.3);
6416
6416
  }
6417
6417
 
6418
6418
  .govuk-tag--red {
6419
- color: #942514;
6420
- background: #f6d7d2;
6419
+ color: rgb(148.4, 37.1, 19.6);
6420
+ background: rgb(246.4, 214.6, 209.6);
6421
6421
  }
6422
6422
 
6423
6423
  .govuk-tag--pink {
6424
- color: #80224d;
6425
- background: #f7d7e6;
6424
+ color: rgb(127.8, 33.6, 76.8);
6425
+ background: rgb(246.6, 215.2, 229.6);
6426
6426
  }
6427
6427
 
6428
6428
  .govuk-tag--green {
6429
- color: #005a30;
6430
- background: #cce2d8;
6429
+ color: rgb(0, 89.6, 48);
6430
+ background: rgb(204, 226.4, 216);
6431
6431
  }
6432
6432
 
6433
6433
  .govuk-phase-banner {
@@ -9334,6 +9334,12 @@ dialog[open] + .backdrop, dialog[open]::backdrop {
9334
9334
  }
9335
9335
  }
9336
9336
 
9337
+ .time-input__item {
9338
+ display: inline-block;
9339
+ margin-right: 20px;
9340
+ margin-bottom: 0;
9341
+ }
9342
+
9337
9343
  .validation-summary {
9338
9344
  padding-left: 11px;
9339
9345
  padding-right: 15px;
@@ -857,6 +857,10 @@ function formFocus() {
857
857
  document.getElementById(getElementFromSummaryLink + '-day').focus();
858
858
  }
859
859
 
860
+ if (document.getElementById(getElementFromSummaryLink + '-hour') && forms.length === 1 && editMode) {
861
+ document.getElementById(getElementFromSummaryLink + '-hour').focus();
862
+ }
863
+
860
864
  if (forms.length > 0) {
861
865
  labels = document.getElementsByTagName('label');
862
866
  if (labels) {