Skip to content

Commit

Permalink
Implements warnings for session timeout / network unavailable #3264
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisala committed Jul 19, 2024
1 parent ec9f36f commit 89dc982
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 52 deletions.
62 changes: 62 additions & 0 deletions grails-app/assets/javascripts/base-bs4.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,65 @@
//= require jquery/jquery.js
//= require js-cookie/js.cookie.js
//= require bootstrap/js/bootstrap.bundle.js
/**
* This function sets up a timeout warning banner that will be displayed when the session has expired
* or network has been lost.
* It is called in the nrm_bs4.gsp template file.
*/
function setupTimeoutWarning(options) {
var $logoutWarningBanner = $('#' + options.logoutWarningBannerId);
var $networkWarningBanner = $('#' + options.networkWarningBannerId);
var $logoutButton = $('#' + options.logoutButtonId);
var $loginButton = $('#' + options.loginButtonId);

// Set up a timer that will periodically poll the server to keep the session alive
var intervalSeconds = 5//; * 60;

function fireKeepAlive() {
$.ajax(options.keepSessionAliveUrl).fail(function (xhr) {
if (xhr.status == 0) {
// Network outage?
$networkWarningBanner.show();
} else if (xhr.status == 401) {
$networkWarningBanner.hide();
// Session timed out.
$logoutWarningBanner.show();
}
}).done(function (xhr) {
$networkWarningBanner.hide();
$logoutWarningBanner.hide();
});
}

setInterval(fireKeepAlive, intervalSeconds * 1000);

if (!window.localStorage) {
return;
}
var LOGOUT_PRESSED_KEY = 'logout';
var LOGIN_PRESSED_KEY = 'login';

$logoutButton.click(function () {
window.localStorage.setItem(LOGOUT_PRESSED_KEY, new Date().getTime());
});
$loginButton.click(function () {
window.localStorage.setItem(LOGIN_PRESSED_KEY, new Date().getTime());
});
$logoutWarningBanner.find('a').click(function () {
$logoutWarningBanner.hide();
});
window.addEventListener('storage', function (e) {
if (e.key == LOGOUT_PRESSED_KEY) {
$logoutWarningBanner.show();
}
if (e.key == LOGIN_PRESSED_KEY) {
$logoutWarningBanner.hide();
}
});
window.addEventListener('online', function() {
$networkWarningBanner.hide();
});
window.addEventListener('offline', function() {
$networkWarningBanner.show();
});
}
14 changes: 0 additions & 14 deletions grails-app/assets/javascripts/fieldcapture-application.js
Original file line number Diff line number Diff line change
Expand Up @@ -934,20 +934,6 @@ function replaceContentSection(contentSelector, url) {
});
}

$(function() {
$('#logout-btn').click(function() {
if (window.localStorage) {
window.localStorage.setItem('logout', new Date().getTime());
}
});
$('#logout-warning a').click(function(){ $('#logout-warning').hide(); });
window.addEventListener('storage', function(e) {
if (e.key == 'logout') {
$('#logout-warning').show();
}
});
});

function stageNumberFromStage(stage) {
var stageRegexp = /.+ (\d+)/;
var match = stageRegexp.exec(stage);
Expand Down
15 changes: 15 additions & 0 deletions grails-app/assets/stylesheets/nrm/css/screen.css
Original file line number Diff line number Diff line change
Expand Up @@ -2444,6 +2444,21 @@ div#announcement p {
margin: 0;
}

div#logout-warning, div#network-warning {
padding: 15px;
font-size: 20px;
font-weight: bold;
text-align: center;
color: white;
background-color: red;
border-bottom: 0px solid red;
}
#logout-warning a:visited, #network-warning a:visited {
color:white;
}



.container-fluid form.search.merit {
display: block;
float: left;
Expand Down
38 changes: 22 additions & 16 deletions grails-app/views/layouts/nrm_bs4.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,18 @@
<fc:announcementContent/>
</div>
</g:if>
<auth:ifLoggedIn>
<div id="logout-warning" style="display:none">
<fc:getSettingContent settingType="${au.org.ala.merit.SettingPageType.SESSION_TIMEOUT_WARNING}"/>
<a href="${fc.loginUrl(loginReturnToUrl:createLink(controller: 'home', action: 'close', absolute: true))}" target="loginWindow">Click here to login again (opens a new window)</a>
</div>
<div id="network-warning" style="display:none">
<fc:getSettingContent settingType="${au.org.ala.merit.SettingPageType.NETWORK_LOST_WARNING}"/>
</div>

<div class="page-header page-header-bs4">
<g:if test="${fc.currentUserDisplayName()}">
<div id="logout-warning" class="d-none">
<div class="alert alert-error text-center">
<strong>You have logged out of MERIT from another tab. Any changes you have made will not be saved to the server until you log back in.</strong>
<fc:loginInNewWindow>Click here to login again (opens a new window)</fc:loginInNewWindow>
</div>
</div>
</g:if>
</auth:ifLoggedIn>

<div class="page-header page-header-bs4">
<div class="navbar navbar-static-top navbar-expand-md navbar-light" id="header">
<div class="${containerType}">
<g:if test="${hubConfig.logoUrl}">
Expand Down Expand Up @@ -204,13 +205,18 @@
}
});
// Set up a timer that will periodically poll the server to keep the session alive
var intervalSeconds = 5 * 60;
setInterval(function () {
$.ajax("${createLink(controller: 'ajax', action:'keepSessionAlive')}").done(function (data) {
});
}, intervalSeconds * 1000);
var options = {
keepSessionAliveUrl: "${g.createLink(controller: 'ajax', action:'keepSessionAlive')}",
logoutWarningBannerId: 'logout-warning',
networkWarningBannerId: 'network-warning',
logoutButtonId: 'btnLogout',
loginButtonId: 'btnLogin'
};
var loggedIn = false;
<auth:ifLoggedIn>
loggedIn = true;
</auth:ifLoggedIn>
setupTimeoutWarning(options);
}); // end document ready
Expand Down
21 changes: 0 additions & 21 deletions grails-app/views/shared/keepAlive.gsp

This file was deleted.

5 changes: 4 additions & 1 deletion src/main/groovy/au/org/ala/merit/SettingPageType.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ enum SettingPageType {
ORGANISATION_REPORT_RETURNED_EMAIL_SUBJECT('organisationReportReturnedEmailSubject', 'Organisation Report returned email subject line text', 'organisation_report.returned.emailSubject'),
ORGANISATION_REPORT_RETURNED_EMAIL_BODY('organisationReportReturnedEmailBody', 'Organisation Report returned email body text', 'organisation_report.returned.emailBody'),
ORGANISATION_REPORT_CONFIG('organisationReportConfig', 'Report configuration options for organisations', 'organisation.availableReportsConfig'),
PLANT_LABEL_INSTRUCTIONS('plantLabelInstructions', 'Instructions for printing plant labels', 'plantLabelInstructions')
PLANT_LABEL_INSTRUCTIONS('plantLabelInstructions', 'Instructions for printing plant labels', 'plantLabelInstructions'),
SESSION_TIMEOUT_WARNING('sessionTimeoutWarning', 'Banner message when a user session has timed out', 'sessionTimeoutWarning'),
NETWORK_LOST_WARNING('networkLostWarning', 'Banner message when MERIT detects the network connection to the server is unavailable', 'networkLostWarning')

String name
String title
String key
Expand Down

0 comments on commit 89dc982

Please sign in to comment.