hof 21.0.20-axios-beta → 22.0.0-timeout-warning-beta.2
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.
- package/.nyc_output/39365c14-40b7-4634-b733-940b72a11984.json +1 -0
- package/.nyc_output/processinfo/39365c14-40b7-4634-b733-940b72a11984.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -1
- package/CHANGELOG.md +16 -0
- package/codeReviewChecklist.md +22 -0
- package/config/hof-defaults.js +11 -2
- package/frontend/govuk-template/build/govuk_template.html +3 -4
- package/frontend/govuk-template/govuk_template_generated.html +3 -4
- package/frontend/template-mixins/mixins/template-mixins.js +1 -0
- package/frontend/template-mixins/partials/forms/checkbox.html +5 -0
- package/frontend/template-mixins/partials/forms/input-text-group.html +1 -1
- package/frontend/template-mixins/partials/forms/select.html +6 -6
- package/frontend/template-mixins/partials/forms/textarea-group.html +1 -1
- package/frontend/template-partials/views/partials/head.html +8 -10
- package/frontend/template-partials/views/partials/page.html +1 -0
- package/frontend/template-partials/views/partials/session-timeout-warning.html +17 -0
- package/frontend/themes/gov-uk/client-js/index.js +2 -0
- package/frontend/themes/gov-uk/client-js/session-timeout-dialog.js +333 -0
- package/frontend/themes/gov-uk/styles/_session-timeout-dialog.scss +209 -0
- package/frontend/themes/gov-uk/styles/govuk.scss +1 -0
- package/index.js +8 -4
- package/lib/ga-tag.js +22 -13
- package/model/index.js +28 -29
- package/package.json +6 -7
- package/pull_request.md +16 -0
- package/sandbox/apps/sandbox/index.js +1 -0
- package/sandbox/package.json +1 -1
- package/sandbox/public/css/app.css +251 -6
- package/sandbox/public/js/bundle.js +36441 -25219
- package/sandbox/yarn.lock +14 -9
- package/.nyc_output/9651d42a-59d8-48e6-949c-655d9fa6db21.json +0 -1
- package/.nyc_output/processinfo/9651d42a-59d8-48e6-949c-655d9fa6db21.json +0 -1
- package/model/apis/axios-settings.js +0 -9
@@ -0,0 +1,333 @@
|
|
1
|
+
/* eslint max-len: 0 */
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
const $ = require('jquery');
|
5
|
+
|
6
|
+
// Modal dialog prototype
|
7
|
+
window.GOVUK.sessionDialog = {
|
8
|
+
el: document.getElementById('js-modal-dialog'),
|
9
|
+
$el: $('#js-modal-dialog'),
|
10
|
+
$lastFocusedEl: null,
|
11
|
+
$closeButton: $('.modal-dialog .js-dialog-close'),
|
12
|
+
dialogIsOpenClass: 'dialog-is-open',
|
13
|
+
timers: [],
|
14
|
+
warningTextPrefix: 'To protect your information, this page will time out in ',
|
15
|
+
warningTextSuffix: '.',
|
16
|
+
warningText: $('.dialog-text').text(),
|
17
|
+
warningTextExtra: '',
|
18
|
+
|
19
|
+
// Timer specific markup. If these are not present, timeout and redirection are disabled
|
20
|
+
$timer: $('#js-modal-dialog .timer'),
|
21
|
+
$accessibleTimer: $('#js-modal-dialog .at-timer'),
|
22
|
+
|
23
|
+
secondsSessionTimeout: parseInt($('#js-modal-dialog').data('session-timeout'), 10 || 1800),
|
24
|
+
secondsTimeoutWarning: parseInt($('#js-modal-dialog').data('session-timeout-warning'), 10 || 300),
|
25
|
+
timeoutRedirectUrl: $('#js-modal-dialog').data('url-redirect'),
|
26
|
+
timeSessionRefreshed: new Date(),
|
27
|
+
|
28
|
+
bindUIElements: function () {
|
29
|
+
window.GOVUK.sessionDialog.$closeButton.on('click', function (e) {
|
30
|
+
e.preventDefault();
|
31
|
+
window.GOVUK.sessionDialog.closeDialog();
|
32
|
+
});
|
33
|
+
|
34
|
+
// Close modal when ESC pressed
|
35
|
+
$(document).keydown(function (e) {
|
36
|
+
if (window.GOVUK.sessionDialog.isDialogOpen() && e.keyCode === 27) {
|
37
|
+
window.GOVUK.sessionDialog.closeDialog();
|
38
|
+
}
|
39
|
+
});
|
40
|
+
},
|
41
|
+
|
42
|
+
isDialogOpen: function () {
|
43
|
+
return window.GOVUK.sessionDialog.el.open;
|
44
|
+
},
|
45
|
+
|
46
|
+
isConfigured: function () {
|
47
|
+
return window.GOVUK.sessionDialog.$timer.length > 0 &&
|
48
|
+
window.GOVUK.sessionDialog.$accessibleTimer.length > 0 &&
|
49
|
+
window.GOVUK.sessionDialog.secondsSessionTimeout &&
|
50
|
+
window.GOVUK.sessionDialog.secondsTimeoutWarning &&
|
51
|
+
window.GOVUK.sessionDialog.timeoutRedirectUrl;
|
52
|
+
},
|
53
|
+
|
54
|
+
openDialog: function () {
|
55
|
+
if (!window.GOVUK.sessionDialog.isDialogOpen()) {
|
56
|
+
$('html, body').addClass(window.GOVUK.sessionDialog.dialogIsOpenClass);
|
57
|
+
window.GOVUK.sessionDialog.saveLastFocusedEl();
|
58
|
+
window.GOVUK.sessionDialog.makePageContentInert();
|
59
|
+
window.GOVUK.sessionDialog.el.showModal();
|
60
|
+
}
|
61
|
+
},
|
62
|
+
|
63
|
+
closeDialog: function () {
|
64
|
+
if (window.GOVUK.sessionDialog.isDialogOpen()) {
|
65
|
+
$('html, body').removeClass(window.GOVUK.sessionDialog.dialogIsOpenClass);
|
66
|
+
window.GOVUK.sessionDialog.el.close();
|
67
|
+
window.GOVUK.sessionDialog.setFocusOnLastFocusedEl();
|
68
|
+
window.GOVUK.sessionDialog.removeInertFromPageContent();
|
69
|
+
window.GOVUK.sessionDialog.refreshSession();
|
70
|
+
}
|
71
|
+
},
|
72
|
+
|
73
|
+
saveLastFocusedEl: function () {
|
74
|
+
window.GOVUK.sessionDialog.$lastFocusedEl = document.activeElement;
|
75
|
+
if (!window.GOVUK.sessionDialog.$lastFocusedEl || window.GOVUK.sessionDialog.$lastFocusedEl === document.body) {
|
76
|
+
window.GOVUK.sessionDialog.$lastFocusedEl = null;
|
77
|
+
} else if (document.querySelector) {
|
78
|
+
window.GOVUK.sessionDialog.$lastFocusedEl = document.querySelector(':focus');
|
79
|
+
}
|
80
|
+
},
|
81
|
+
|
82
|
+
// Set focus back on last focused el when modal closed
|
83
|
+
setFocusOnLastFocusedEl: function () {
|
84
|
+
if (window.GOVUK.sessionDialog.$lastFocusedEl) {
|
85
|
+
window.setTimeout(function () {
|
86
|
+
window.GOVUK.sessionDialog.$lastFocusedEl.focus();
|
87
|
+
}, 0);
|
88
|
+
}
|
89
|
+
},
|
90
|
+
|
91
|
+
// Set page content to inert to indicate to screenreaders it's inactive
|
92
|
+
// NB: This will look for #content for toggling inert state
|
93
|
+
makePageContentInert: function () {
|
94
|
+
if (document.querySelector('#content')) {
|
95
|
+
document.querySelector('#content').inert = true;
|
96
|
+
document.querySelector('#content').setAttribute('aria-hidden', 'true');
|
97
|
+
}
|
98
|
+
},
|
99
|
+
|
100
|
+
// Make page content active when modal is not open
|
101
|
+
// NB: This will look for #content for toggling inert state
|
102
|
+
removeInertFromPageContent: function () {
|
103
|
+
if (document.querySelector('#content')) {
|
104
|
+
document.querySelector('#content').inert = false;
|
105
|
+
document.querySelector('#content').setAttribute('aria-hidden', 'false');
|
106
|
+
}
|
107
|
+
},
|
108
|
+
|
109
|
+
numberToWords: function (n) {
|
110
|
+
const string = n.toString();
|
111
|
+
let start;
|
112
|
+
let end;
|
113
|
+
let chunk;
|
114
|
+
let ints;
|
115
|
+
let i;
|
116
|
+
let word;
|
117
|
+
let words = 'and';
|
118
|
+
|
119
|
+
if (parseInt(string, 10) === 0) {
|
120
|
+
return 'zero';
|
121
|
+
}
|
122
|
+
|
123
|
+
/* Array of units as words */
|
124
|
+
const units = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
|
125
|
+
|
126
|
+
/* Array of tens as words */
|
127
|
+
const tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
|
128
|
+
|
129
|
+
/* Array of scales as words */
|
130
|
+
const scales = ['', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quatttuor-decillion', 'quindecillion', 'sexdecillion', 'septen-decillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'centillion'];
|
131
|
+
|
132
|
+
/* Split user arguemnt into 3 digit chunks from right to left */
|
133
|
+
start = string.length;
|
134
|
+
const chunks = [];
|
135
|
+
while (start > 0) {
|
136
|
+
end = start;
|
137
|
+
chunks.push(string.slice((start = Math.max(0, start - 3)), end));
|
138
|
+
}
|
139
|
+
|
140
|
+
/* Check if function has enough scale words to be able to stringify the user argument */
|
141
|
+
const chunksLen = chunks.length;
|
142
|
+
if (chunksLen > scales.length) {
|
143
|
+
return '';
|
144
|
+
}
|
145
|
+
|
146
|
+
/* Stringify each integer in each chunk */
|
147
|
+
words = [];
|
148
|
+
for (i = 0; i < chunksLen; i++) {
|
149
|
+
chunk = parseInt(chunks[i], 10);
|
150
|
+
|
151
|
+
if (chunk) {
|
152
|
+
/* Split chunk into array of individual integers */
|
153
|
+
ints = chunks[i].split('').reverse().map(parseFloat);
|
154
|
+
|
155
|
+
/* If tens integer is 1, i.e. 10, then add 10 to units integer */
|
156
|
+
if (ints[1] === 1) {
|
157
|
+
ints[0] += 10;
|
158
|
+
}
|
159
|
+
|
160
|
+
/* Add scale word if chunk is not zero and array item exists */
|
161
|
+
if ((word === scales[i])) {
|
162
|
+
words.push(word);
|
163
|
+
}
|
164
|
+
|
165
|
+
/* Add unit word if array item exists */
|
166
|
+
if ((word === units[ints[0]])) {
|
167
|
+
words.push(word);
|
168
|
+
}
|
169
|
+
|
170
|
+
/* Add tens word if array item exists */
|
171
|
+
if ((word === tens[ints[1]])) {
|
172
|
+
words.push(word);
|
173
|
+
}
|
174
|
+
|
175
|
+
/* Add hundreds word if array item exists */
|
176
|
+
if ((word === units[ints[2]])) {
|
177
|
+
words.push(word + ' hundred');
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
return words.reverse().join(' ');
|
182
|
+
},
|
183
|
+
|
184
|
+
// Attempt to convert numerics into text as OS VoiceOver
|
185
|
+
// occasionally stalled when encountering numbers
|
186
|
+
timeToWords: function (t, unit) {
|
187
|
+
let words;
|
188
|
+
if (t > 0) {
|
189
|
+
try {
|
190
|
+
words = window.GOVUK.sessionDialog.numberToWords(t);
|
191
|
+
} catch (e) {
|
192
|
+
words = t;
|
193
|
+
}
|
194
|
+
words = words + ' ' + window.GOVUK.sessionDialog.pluralise(t, unit);
|
195
|
+
} else {
|
196
|
+
words = '';
|
197
|
+
}
|
198
|
+
return words;
|
199
|
+
},
|
200
|
+
|
201
|
+
pluralise: function (n, unit) {
|
202
|
+
return n === 1 ? unit : unit + 's';
|
203
|
+
},
|
204
|
+
|
205
|
+
numericSpan: function (n, unit) {
|
206
|
+
return '<span class="tabular-numbers">' + n + '</span> ' + window.GOVUK.sessionDialog.pluralise(n, unit);
|
207
|
+
},
|
208
|
+
|
209
|
+
countdownText: function (minutes, seconds) {
|
210
|
+
const minutesText = window.GOVUK.sessionDialog.numericSpan(minutes, 'minute');
|
211
|
+
const secondsText = window.GOVUK.sessionDialog.numericSpan(seconds, 'second');
|
212
|
+
return minutes > 0 ? minutesText : secondsText;
|
213
|
+
},
|
214
|
+
|
215
|
+
countdownAtText: function (minutes, seconds) {
|
216
|
+
const minutesText = window.GOVUK.sessionDialog.timeToWords(minutes, 'minute');
|
217
|
+
const secondsText = window.GOVUK.sessionDialog.timeToWords(seconds, 'second');
|
218
|
+
return minutes > 0 ? minutesText : secondsText;
|
219
|
+
},
|
220
|
+
|
221
|
+
startCountdown: function () {
|
222
|
+
const $timer = window.GOVUK.sessionDialog.$timer;
|
223
|
+
const $accessibleTimer = window.GOVUK.sessionDialog.$accessibleTimer;
|
224
|
+
let timerRunOnce = false;
|
225
|
+
const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
226
|
+
|
227
|
+
const seconds = window.GOVUK.sessionDialog.secondsUntilSessionTimeout();
|
228
|
+
const minutes = seconds / 60;
|
229
|
+
|
230
|
+
$timer.text(minutes + ' minute' + (minutes > 1 ? 's' : ''));
|
231
|
+
|
232
|
+
(function countdown() {
|
233
|
+
const secondsUntilSessionTimeout = window.GOVUK.sessionDialog.secondsUntilSessionTimeout();
|
234
|
+
const timerExpired = secondsUntilSessionTimeout <= window.GOVUK.sessionDialog.secondsFinalWarning;
|
235
|
+
|
236
|
+
if (!timerExpired) {
|
237
|
+
const minutesLeft = parseInt(secondsUntilSessionTimeout / 60, 10);
|
238
|
+
const secondsLeft = parseInt(secondsUntilSessionTimeout % 60, 10);
|
239
|
+
const atMinutesText = window.GOVUK.sessionDialog.timeToWords(minutesLeft, 'minute');
|
240
|
+
const atSecondsText = window.GOVUK.sessionDialog.timeToWords(secondsLeft, 'second');
|
241
|
+
|
242
|
+
// Below string will get read out by screen readers every time
|
243
|
+
// the timeout refreshes.
|
244
|
+
// Add additional information in extraText which will get announced to AT the
|
245
|
+
// first time the time out opens
|
246
|
+
const countdownText = window.GOVUK.sessionDialog.countdownText(minutesLeft, secondsLeft);
|
247
|
+
const text = window.GOVUK.sessionDialog.warningTextPrefix + '<strong>' + countdownText + '</strong>' + window.GOVUK.sessionDialog.warningTextSuffix;
|
248
|
+
const countdownAtText = window.GOVUK.sessionDialog.countdownAtText(atMinutesText, atSecondsText);
|
249
|
+
const atText = window.GOVUK.sessionDialog.warningTextPrefix + countdownAtText + window.GOVUK.sessionDialog.warningTextSuffix + 'bgbhj ' + window.GOVUK.sessionDialog.warningText;
|
250
|
+
const extraText = '\n' + window.GOVUK.sessionDialog.warningTextExtra;
|
251
|
+
|
252
|
+
$timer.html(text + ' ' + extraText);
|
253
|
+
|
254
|
+
// Update screen reader friendly content every 20 secs
|
255
|
+
if (secondsLeft % 20 === 0) {
|
256
|
+
// Read out the extra content only once.
|
257
|
+
// Don't read out on iOS VoiceOver which stalls on the longer text
|
258
|
+
if (!timerRunOnce && !iOS) {
|
259
|
+
$accessibleTimer.text(atText + extraText);
|
260
|
+
timerRunOnce = true;
|
261
|
+
} else {
|
262
|
+
$accessibleTimer.text(atText);
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
window.GOVUK.sessionDialog.addTimer(countdown, 20);
|
267
|
+
}
|
268
|
+
})();
|
269
|
+
},
|
270
|
+
|
271
|
+
// Clears all timers
|
272
|
+
clearTimers: function () {
|
273
|
+
for (let i = 0; i < window.GOVUK.sessionDialog.timers.length; i++) {
|
274
|
+
clearInterval(window.GOVUK.sessionDialog.timers[i]);
|
275
|
+
}
|
276
|
+
},
|
277
|
+
|
278
|
+
refreshSession: function () {
|
279
|
+
$.get('');
|
280
|
+
window.GOVUK.sessionDialog.timeSessionRefreshed = new Date();
|
281
|
+
window.GOVUK.sessionDialog.controller();
|
282
|
+
},
|
283
|
+
|
284
|
+
redirect: function () {
|
285
|
+
window.location = window.GOVUK.sessionDialog.timeoutRedirectUrl;
|
286
|
+
},
|
287
|
+
|
288
|
+
// JS doesn't allow resetting timers globally so timers need
|
289
|
+
// to be retained for resetting.
|
290
|
+
addTimer: function (f, seconds) {
|
291
|
+
window.GOVUK.sessionDialog.timers.push(setInterval(f, seconds * 1000));
|
292
|
+
},
|
293
|
+
|
294
|
+
secondsSinceRefresh: function () {
|
295
|
+
return Math.round(Math.abs((window.GOVUK.sessionDialog.timeSessionRefreshed - new Date()) / 1000));
|
296
|
+
},
|
297
|
+
|
298
|
+
secondsUntilSessionTimeout: function () {
|
299
|
+
return window.GOVUK.sessionDialog.secondsSessionTimeout - window.GOVUK.sessionDialog.secondsSinceRefresh();
|
300
|
+
},
|
301
|
+
|
302
|
+
secondsUntilTimeoutWarning: function () {
|
303
|
+
return window.GOVUK.sessionDialog.secondsUntilSessionTimeout() - window.GOVUK.sessionDialog.secondsTimeoutWarning;
|
304
|
+
},
|
305
|
+
|
306
|
+
// countdown controller logic
|
307
|
+
controller: function () {
|
308
|
+
window.GOVUK.sessionDialog.clearTimers();
|
309
|
+
|
310
|
+
const secondsUntilSessionTimeout = window.GOVUK.sessionDialog.secondsUntilSessionTimeout();
|
311
|
+
|
312
|
+
if (secondsUntilSessionTimeout <= 0) {
|
313
|
+
// timed out - redirect
|
314
|
+
window.GOVUK.sessionDialog.redirect();
|
315
|
+
} else if (secondsUntilSessionTimeout <= window.GOVUK.sessionDialog.secondsTimeoutWarning) {
|
316
|
+
// timeout warning - show countdown and schedule redirect
|
317
|
+
window.GOVUK.sessionDialog.openDialog();
|
318
|
+
window.GOVUK.sessionDialog.startCountdown();
|
319
|
+
window.GOVUK.sessionDialog.addTimer(window.GOVUK.sessionDialog.controller, window.GOVUK.sessionDialog.secondsUntilSessionTimeout());
|
320
|
+
} else {
|
321
|
+
// wait for warning
|
322
|
+
window.GOVUK.sessionDialog.addTimer(window.GOVUK.sessionDialog.controller, window.GOVUK.sessionDialog.secondsUntilTimeoutWarning());
|
323
|
+
}
|
324
|
+
},
|
325
|
+
|
326
|
+
init: function (options) {
|
327
|
+
$.extend(window.GOVUK.sessionDialog, options);
|
328
|
+
if (window.GOVUK.sessionDialog.el && window.GOVUK.sessionDialog.isConfigured()) {
|
329
|
+
window.GOVUK.sessionDialog.bindUIElements();
|
330
|
+
window.GOVUK.sessionDialog.controller();
|
331
|
+
}
|
332
|
+
}
|
333
|
+
};
|
@@ -0,0 +1,209 @@
|
|
1
|
+
.modal-dialog {
|
2
|
+
display: none;
|
3
|
+
}
|
4
|
+
|
5
|
+
.modal-dialog--no-js-persistent {
|
6
|
+
display: inline-block;
|
7
|
+
}
|
8
|
+
|
9
|
+
.js-enabled {
|
10
|
+
.modal-dialog--no-js-persistent {
|
11
|
+
display: none;
|
12
|
+
|
13
|
+
&[open], .dialog-button {
|
14
|
+
display: inline-block;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
.modal-dialog[open] {
|
19
|
+
display: inline-block;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
.modal-dialog[open] {
|
24
|
+
overflow-x: hidden;
|
25
|
+
overflow-y: auto;
|
26
|
+
max-height: 90vh;
|
27
|
+
padding: 0;
|
28
|
+
margin-bottom: 0;
|
29
|
+
margin-top: 0;
|
30
|
+
position: fixed;
|
31
|
+
top: 50% !important;
|
32
|
+
-webkit-transform: translate(0, -50%);
|
33
|
+
-ms-transform: translate(0, -50%);
|
34
|
+
transform: translate(0, -50%);
|
35
|
+
}
|
36
|
+
|
37
|
+
@media (min-width: 641px) {
|
38
|
+
.modal-dialog[open] {
|
39
|
+
padding: 0;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
.modal-dialog__inner {
|
44
|
+
padding: 20px;
|
45
|
+
}
|
46
|
+
|
47
|
+
@media (min-width: 641px) {
|
48
|
+
.modal-dialog__inner {
|
49
|
+
padding: 30px;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
.modal-dialog__inner__text {
|
54
|
+
font-family: "nta", Arial, sans-serif;
|
55
|
+
font-weight: 400;
|
56
|
+
text-transform: none;
|
57
|
+
font-size: 16px;
|
58
|
+
line-height: 1.25;
|
59
|
+
padding-top: 2px;
|
60
|
+
padding-bottom: 8px;
|
61
|
+
margin-bottom: 20px;
|
62
|
+
}
|
63
|
+
|
64
|
+
@media (min-width: 641px) {
|
65
|
+
.modal-dialog__inner__text {
|
66
|
+
font-size: 19px;
|
67
|
+
line-height: 1.31579;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
@media (min-width: 641px) {
|
72
|
+
.modal-dialog__inner__text {
|
73
|
+
padding-top: 0;
|
74
|
+
padding-bottom: 5px;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
.modal-dialog__inner__button {
|
79
|
+
font-size: 19px;
|
80
|
+
margin-top: 10px;
|
81
|
+
}
|
82
|
+
|
83
|
+
.modal-dialog__inner__link {
|
84
|
+
font-family: "nta", Arial, sans-serif;
|
85
|
+
font-weight: 400;
|
86
|
+
text-transform: none;
|
87
|
+
font-size: 16px;
|
88
|
+
line-height: 1.25;
|
89
|
+
padding-top: 2px;
|
90
|
+
padding-bottom: 8px;
|
91
|
+
background: none;
|
92
|
+
border: none;
|
93
|
+
vertical-align: middle;
|
94
|
+
margin-top: 20px;
|
95
|
+
|
96
|
+
&:hover {
|
97
|
+
cursor: pointer;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
@media (min-width: 641px) {
|
102
|
+
.modal-dialog__inner__link {
|
103
|
+
font-size: 19px;
|
104
|
+
line-height: 1.31579;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
@media (min-width: 641px) {
|
109
|
+
.modal-dialog__inner__link {
|
110
|
+
padding-top: 0;
|
111
|
+
padding-bottom: 5px;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
@media (max-width: 640px) {
|
116
|
+
.modal-dialog__inner__link {
|
117
|
+
text-align: center;
|
118
|
+
display: block;
|
119
|
+
margin-top: 25px;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
@media (min-width: 641px) {
|
124
|
+
.modal-dialog__inner__link {
|
125
|
+
position: absolute;
|
126
|
+
top: 50%;
|
127
|
+
transform: translateY(-50%);
|
128
|
+
padding: 0;
|
129
|
+
margin: 0 0 0 30px;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
.modal-dialog__inner__block {
|
134
|
+
position: relative;
|
135
|
+
}
|
136
|
+
|
137
|
+
.modal-dialog #dialog-title {
|
138
|
+
margin-top: 0;
|
139
|
+
}
|
140
|
+
|
141
|
+
.dialog-is-open {
|
142
|
+
overflow: hidden;
|
143
|
+
}
|
144
|
+
|
145
|
+
dialog {
|
146
|
+
left: 0;
|
147
|
+
right: 0;
|
148
|
+
width: -moz-fit-content;
|
149
|
+
width: -webkit-fit-content;
|
150
|
+
width: fit-content;
|
151
|
+
height: -moz-fit-content;
|
152
|
+
height: -webkit-fit-content;
|
153
|
+
height: fit-content;
|
154
|
+
margin: auto;
|
155
|
+
border: solid;
|
156
|
+
padding: 1em;
|
157
|
+
background: white;
|
158
|
+
color: black;
|
159
|
+
display: none;
|
160
|
+
border: 5px solid black;
|
161
|
+
|
162
|
+
+ .backdrop {
|
163
|
+
position: fixed;
|
164
|
+
top: 0;
|
165
|
+
right: 0;
|
166
|
+
bottom: 0;
|
167
|
+
left: 0;
|
168
|
+
background: rgba(0, 0, 0, 0.8);
|
169
|
+
}
|
170
|
+
|
171
|
+
&[open] {
|
172
|
+
display: block;
|
173
|
+
box-sizing: border-box;
|
174
|
+
margin: 0 auto;
|
175
|
+
padding: 15px;
|
176
|
+
width: 90%;
|
177
|
+
|
178
|
+
+ .backdrop, &::backdrop {
|
179
|
+
background: rgba(0, 0, 0, 0.8);
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
@media (min-width: 641px) {
|
185
|
+
dialog[open] {
|
186
|
+
padding: 30px;
|
187
|
+
margin: 30px auto;
|
188
|
+
max-width: 500px;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
.tabular-numbers {
|
193
|
+
font-family: "ntatabularnumbers", "nta", Arial, sans-serif;
|
194
|
+
}
|
195
|
+
|
196
|
+
.dialog-sign-out-link {
|
197
|
+
@include govuk-font($size: 24);
|
198
|
+
display: inline-block;
|
199
|
+
margin: 5px;
|
200
|
+
|
201
|
+
@include govuk-media-query($from: tablet) {
|
202
|
+
@include govuk-font($size: 19);
|
203
|
+
|
204
|
+
position: relative;
|
205
|
+
top: 2px;
|
206
|
+
padding: 0.526315em 0.789473em 0.263157em;
|
207
|
+
line-height: 1.5;
|
208
|
+
}
|
209
|
+
}
|
package/index.js
CHANGED
@@ -84,6 +84,7 @@ const getContentSecurityPolicy = (config, res) => {
|
|
84
84
|
'www.google.co.uk/ads/ga-audiences'
|
85
85
|
],
|
86
86
|
connectSrc: [
|
87
|
+
"'self'",
|
87
88
|
'https://www.google-analytics.com',
|
88
89
|
'https://region1.google-analytics.com',
|
89
90
|
'https://region1.analytics.google.com'
|
@@ -147,6 +148,9 @@ function bootstrap(options) {
|
|
147
148
|
res.locals.appName = config.appName;
|
148
149
|
res.locals.htmlLang = config.htmlLang;
|
149
150
|
res.locals.cookieName = config.session.name;
|
151
|
+
// session timeout warning configs
|
152
|
+
res.locals.sessionTimeOut = config.session.ttl;
|
153
|
+
res.locals.sessionTimeOutWarning = config.sessionTimeOutWarning;
|
150
154
|
next();
|
151
155
|
});
|
152
156
|
|
@@ -189,10 +193,10 @@ function bootstrap(options) {
|
|
189
193
|
app.use(morgan('sessionId=:id ' + morgan.combined, {
|
190
194
|
stream: config.logger.stream,
|
191
195
|
skip: (req, res) => config.loglevel !== 'debug' &&
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
+
(
|
197
|
+
res.statusCode >= 300 || !_.get(req, 'session.id') ||
|
198
|
+
config.ignoreMiddlewareLogs.some(v => req.originalUrl.includes(v))
|
199
|
+
)
|
196
200
|
}));
|
197
201
|
|
198
202
|
serveStatic(app, config);
|
package/lib/ga-tag.js
CHANGED
@@ -52,26 +52,35 @@ const setupPageMap = routes => {
|
|
52
52
|
module.exports = (app, config) => {
|
53
53
|
const gaTagId = config.gaTagId;
|
54
54
|
const ga4TagId = config.ga4TagId;
|
55
|
-
const
|
56
|
-
const environmentType = config.environmentType ? config.environmentType : 'dev';
|
55
|
+
const gtm = config.gtm;
|
57
56
|
const gaCrossDomainTrackingTagId = config.gaCrossDomainTrackingTagId;
|
58
57
|
const routes = config.routes;
|
59
58
|
|
60
|
-
if (gaTagId || ga4TagId) {
|
59
|
+
if (gaTagId || ga4TagId || gtm.tagId) {
|
61
60
|
const pageMap = setupPageMap(routes);
|
62
61
|
|
63
62
|
app.use((req, res, next) => {
|
64
63
|
const page = pageView(req.path, pageMap);
|
65
|
-
|
66
|
-
res.locals
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
64
|
+
|
65
|
+
// Preparing common res.locals properties
|
66
|
+
const properties = {
|
67
|
+
gaAllowDebug: config.env === 'development',
|
68
|
+
gaTagId: gaTagId,
|
69
|
+
ga4TagId: ga4TagId,
|
70
|
+
gaCrossDomainTrackingTagId: gaCrossDomainTrackingTagId,
|
71
|
+
'ga-id': gaTagId,
|
72
|
+
'ga-page': page
|
73
|
+
};
|
74
|
+
|
75
|
+
// Adding extra properties if a GTM TAG is available
|
76
|
+
if (gtm.tagId) {
|
77
|
+
gtm.config.pageName = gtm.composePageName(page, convertToGTMPage);
|
78
|
+
Object.assign(properties, {
|
79
|
+
gtmConfig: JSON.stringify(gtm.config),
|
80
|
+
gtmTagId: gtm.tagId
|
81
|
+
});
|
82
|
+
}
|
83
|
+
res.locals = Object.assign(res.locals, properties);
|
75
84
|
next();
|
76
85
|
});
|
77
86
|
}
|