From 6e09d1afaa72f728e4190e54f42080263f7ec359 Mon Sep 17 00:00:00 2001 From: swapnamol-abraham Date: Wed, 27 May 2026 15:04:39 +0100 Subject: [PATCH] TD-6515: New error messages for time out --- .../vuesrc/learningsessions/ScormViewer.vue | 112 ++++++++++++--- .../models/learningsessions/scormApiModel.ts | 10 +- .../Styles/layout/_layout.scss | 31 +++++ .../Views/Home/SessionTimeout.cshtml | 6 +- LearningHub.Nhs.WebUI/wwwroot/js/site.js | 127 ++++++++++++++++-- 5 files changed, 249 insertions(+), 37 deletions(-) diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/learningsessions/ScormViewer.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/learningsessions/ScormViewer.vue index 93006121a..058814f53 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/learningsessions/ScormViewer.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/learningsessions/ScormViewer.vue @@ -1,24 +1,54 @@  @@ -34,7 +64,8 @@ return { scormApi: null as ScormApiModel, textLog: '', - textLogVisible: false + textLogVisible: false, + showLmsErrorModal: false }; }, computed: { @@ -55,8 +86,16 @@ this.textLog += value.statement + '\n'; }) this.textLogVisible = true; + }, + closeLmsError() { + this.showLmsErrorModal = false; } - } + }, + mounted() { + window.addEventListener('show-lms-error', () => { + this.showLmsErrorModal = true; + }); + }, }) diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/models/learningsessions/scormApiModel.ts b/LearningHub.Nhs.WebUI/Scripts/vuesrc/models/learningsessions/scormApiModel.ts index 8555d67d9..08453eb7b 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/models/learningsessions/scormApiModel.ts +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/models/learningsessions/scormApiModel.ts @@ -152,7 +152,8 @@ export class ScormApiModel { this.LMSLastErrorCode = 301; this.LMSLastErrorMsg = "Unable to disconnect cleanly from the e-LfH LMS"; - alert("Error communicating with the LMS server. Your learning details may not have been saved."); + //alert("Error communicating with the LMS server. Your learning details may not have been saved."); + window.dispatchEvent(new CustomEvent('show-lms-error')); } result = false; @@ -821,8 +822,9 @@ export class ScormApiModel { this.LMSLastErrorCode = 101; this.LMSLastErrorMsg = "LMSCommit failed. Unable to communicate with the LMS."; - alert("Error communicating with the LMS server. Your learning details may not have been saved.\n\n" + - "If the error persists please email support@learninghub.nhs.uk for further assistance."); + window.dispatchEvent(new CustomEvent('show-lms-error')); + //alert("Error communicating with the LMS server. Your learning details may not have been saved.\n\n" + + // "If the error persists please email support@learninghub.nhs.uk for further assistance."); } result = false; @@ -1113,4 +1115,4 @@ export class ScormApiModel { return response; } -} +} \ No newline at end of file diff --git a/LearningHub.Nhs.WebUI/Styles/layout/_layout.scss b/LearningHub.Nhs.WebUI/Styles/layout/_layout.scss index c2ef190b0..c051407d6 100644 --- a/LearningHub.Nhs.WebUI/Styles/layout/_layout.scss +++ b/LearningHub.Nhs.WebUI/Styles/layout/_layout.scss @@ -374,3 +374,34 @@ input:required:invalid, input:focus:invalid { i { color: #4C6272; } +.session-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 9999; +} + +.session-modal { + background: #fff; + padding: 30px; + border-radius: 8px; + width: 500px; + max-width: 90%; + text-align: center; +} + +.session-modal h2 { + margin-top: 0; +} + +.session-modal button { + margin-top: 20px; + padding: 10px 20px; + cursor: pointer; +} \ No newline at end of file diff --git a/LearningHub.Nhs.WebUI/Views/Home/SessionTimeout.cshtml b/LearningHub.Nhs.WebUI/Views/Home/SessionTimeout.cshtml index 17e7f0852..6239c3ede 100644 --- a/LearningHub.Nhs.WebUI/Views/Home/SessionTimeout.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Home/SessionTimeout.cshtml @@ -4,7 +4,7 @@
-

You have been signed out

-

You have been signed out as there has been no activity for at least @ViewBag.AuthTimeout minutes.

-

Sign in to the Learning Hub

+

Your session has timed out

+

There’s been no activity for @ViewBag.AuthTimeout minutes. You will need to log in again to continue.

+

Log in to the Learning Hub

\ No newline at end of file diff --git a/LearningHub.Nhs.WebUI/wwwroot/js/site.js b/LearningHub.Nhs.WebUI/wwwroot/js/site.js index 9fb9279ca..1da2c3007 100644 --- a/LearningHub.Nhs.WebUI/wwwroot/js/site.js +++ b/LearningHub.Nhs.WebUI/wwwroot/js/site.js @@ -20,39 +20,138 @@ $(function () { }); LHGlobal.sessionManager = new function () { + var sm = this; var _idleTime = 0; + var _warningTime = 2 * 60 * 1000; // 15 minutes + var _sessionTimeout = 3 * 60 * 1000; // 20 minutes + var _on = false; - var _sessionTimeout = 0; + var _warningShown = false; + var _interval = null; var _run = function () { + _idleTime += 1000; - if (_idleTime > _sessionTimeout) { + + // Show warning after 15 mins + if (_idleTime >= _warningTime && !_warningShown) { + _warningShown = true; + sm.showWarning(); + } + + // Timeout after 20 mins + if (_idleTime >= _sessionTimeout) { sm.showMessage(); } - } + }; var _start = function () { - if (_on) { - setInterval(_run, 1000); - //console.log(new Date().toLocaleTimeString(), 'session started..'); + + if (_on && !_interval) { + _interval = setInterval(_run, 1000); } - } + }; + + sm.init = function () { - sm.init = function (timeoutInMin) { - _sessionTimeout = timeoutInMin * 60000; _on = true; - } + + // Reset inactivity timer on user activity + [ + 'click', + 'mousemove', + 'keypress', + 'scroll', + 'touchstart' + ].forEach(function (event) { + + window.addEventListener(event, sm.reset); + }); + }; sm.reset = function () { + _idleTime = 0; - //console.log(new Date().toLocaleTimeString(), 'session reset..'); - } + _warningShown = false; + + // Remove warning popup if exists + var warning = document.getElementById('session-warning'); + + if (warning) { + warning.remove(); + } + }; + + sm.showWarning = function () { + + // Prevent duplicate popup + if (document.getElementById('session-warning')) { + return; + } + + var modal = document.createElement('div'); + + modal.id = 'session-warning'; + + modal.innerHTML = ` +
+
+ +

You’re about to be logged out

+ +

+ You’ve been inactive for 15 minutes. + If you don’t take action, your session will end in 5 minutes. +

+ +

+ Your progress will not be saved. +

+ + + +
+
+ `; + + document.body.appendChild(modal); + + // Stay logged in button + document + .getElementById('stay-logged-in') + .addEventListener('click', function () { + + sm.reset(); + }); + + // Click anywhere in overlay + modal.addEventListener('click', function () { + + sm.reset(); + }); + }; sm.showMessage = function () { - window.location.href = '/session-timeout?returnUrl=' + encodeURIComponent(window.location.href); - } + // Stop interval + if (_interval) { + clearInterval(_interval); + _interval = null; + } + + // Remove warning popup + var warning = document.getElementById('session-warning'); + + if (warning) { + warning.remove(); + } + window.location.href = + '/session-timeout?returnUrl=' + + encodeURIComponent(window.location.href); + }; window.addEventListener('load', _start);