/* * app.shell.js * Shell module for SPA */ /*jslint browser : true, continue : true, devel : true, indent : 2, maxerr : 50, newcap : true, nomen : true, plusplus : true, regexp : true, sloppy : true, vars : false, white : true */ /*global $, app */ app.shell = (function () { 'use strict'; //---------------- BEGIN MODULE SCOPE VARIABLES -------------- var stateMap = { $container: undefined, anchor_map: {}, user: { authenticated: false, token: '', name: '', id: 0 }, apiUrl: '', search_cache: { has_cache: false } }, tokenExpired, //onUPdate, onLogin, onLogout, onShowError, onClearError, initModule; //----------------- END MODULE SCOPE VARIABLES --------------- //------------------- BEGIN UTILITY METHODS ------------------ tokenExpired = function () { //fetch stored creds if available var creds = store.get('rockfish.usercreds'); if (creds) { //check if token has expired //is the date greater than the expires date var rightNowUtc = new Date(); var expDate = new Date(creds.expires * 1000); if (rightNowUtc > expDate) { return true; } else { return false; } } else { return true; } } //-------------------- END UTILITY METHODS ------------------- //------------------- BEGIN EVENT HANDLERS ------------------- onLogin = function (event, login_user) { //store creds store.set('rockfish.usercreds', stateMap.user); //New token needs to reset lastNav stateMap.lastNav = new Date(); //Go to the home page page('#!/customers/'); return false; }; onLogout = function (event) { store.clear(); stateMap.user.authenticated = false; stateMap.user.name = ''; stateMap.user.token = ''; stateMap.user.id = 0; page('#!/authenticate/'); return false; }; // onUpdate = function (event) { // window.location.reload(true); // return false; // }; onShowError = function (event, msg) { $("#app-error-div").removeClass("d-none"); $('#app-error-message').text(msg); return false; }; onClearError = function (event) { $("#app-error-div").addClass("d-none"); return false; }; //-------------------- END EVENT HANDLERS -------------------- //------------------- BEGIN PUBLIC METHODS ------------------- initModule = function ($container) { document.title = 'Rockfish ' + app.api.RockFishVersion; //PRE FLIGHT CHECK //================ //local storage required if (!store.enabled) { alert('Local storage is not supported by your browser. Please disable "Private Mode", or upgrade to a modern browser.'); return; } //wait indicator for ajax functions $(document).ajaxStart(function () { //disable all buttons $('.app-frm-buttons button').prop('disabled', true).addClass('disabled'); //$('.app-frm-buttons button').attr('disabled', 'disabled'); $("body").css("cursor", "progress"); //add app-ajax-busy style to buttons div where user clicked $('.app-frm-buttons').addClass('app-ajax-busy'); }).ajaxStop(function () { //with delay in case it's too fast to see setTimeout(function () { $('.app-frm-buttons button').prop('disabled', false).removeClass('disabled'); //$('.app-frm-buttons button').removeAttr('disabled'); $("body").css("cursor", "default"); $('.app-frm-buttons').removeClass('app-ajax-busy'); }, 250); }); //save on app so can call from anywhere // app.mdInit = mdInit; // load HTML and map jQuery collections stateMap.$container = $container; $container.html(Handlebars.templates['app.shell']({})); //auto hide navbar on click //rfac is a class only on the items that should trigger collapse $('.rfac').on('click', function () { $('.navbar-collapse').collapse('hide'); }); //SEARCH // $('#searchbutton').bind('click', onSearch); //determine API url and save it stateMap.apiUrl = app.utilB.getApiUrl(); //fetch stored creds if available var creds = store.get('rockfish.usercreds'); // if (creds) { //check if token has expired if (tokenExpired()) { stateMap.user.authenticated = false; stateMap.user.name = ''; stateMap.user.token = ''; stateMap.user.id = 0; } else { //Show the logout item in the menu $(".app-mnu-logout").removeClass("app-hidden"); stateMap.user.authenticated = true; stateMap.user.name = creds.name; stateMap.user.token = creds.token; stateMap.user.id = creds.id; } //} //EVENT SUBSCRIPTIONS $.gevent.subscribe($container, 'app-login', onLogin); $.gevent.subscribe($container, 'app-logout', onLogout); //$.gevent.subscribe($container, 'rf-update', onUpdate); $.gevent.subscribe($container, 'app-show-error', onShowError); $.gevent.subscribe($container, 'app-clear-error', onClearError); //ROUTES // page.base('/default.htm'); page('*', beforeUrlChange); page('/authenticate', authenticate); page('/', inbox); page('/reportData', reportData); page('/reportDataProdEmails', reportDataProdEmail); page('/reportDataExpires', reportDataExpires); page('/search', search); page('/logout', function () { $.gevent.publish('app-logout'); }); page('/customers', customers); page('/customerEdit/:id', customerEdit); page('/customerSites/:id', customerSites); page('/customerSiteEdit/:id/:cust_id', customerSiteEdit); page('/purchases/:id', purchases); page('/purchaseEdit/:id/:site_id', purchaseEdit); page('/license', license); page('/licenseTemplates', licenseTemplates); page('/licenseRequests', licenseRequests); page('/licenseRequestEdit/:id', licenseRequestEdit); //case 3233 page('/licenses', licenses); page('/licenseView/:id', licenseView); page('/subscription', subscription); page('/subnotify', subnotify); page('/templates', templates); page('/templateEdit/:id', templateEdit); page('/inbox', inbox); page.exit('/inbox', function(ctx,next) { app.inbox.terminateModule(); next(); }); page('/mailEdit/:mail_account/:mail_folder/:mail_id', mailEdit); page('/rfcases', rfcases); page('/rfcaseEdit/:id', rfcaseEdit); page('/rfsettings', rfsettings); page('/ops', ops); page('/trials', trials); page('/trialEdit/:id', trialEdit); page('*', notFound); page({ hashbang: true }); // /ROUTES }; // End PUBLIC method /initModule/ var beforeUrlChange = function (ctx, next) { $.gevent.publish('app-clear-error'); app.shell.stateMap.mediaSize = app.utilB.getMediaSize(); //case 3513 document.title = 'Rockfish ' + app.api.RockFishVersion; //bypass stuff below if about to logout if (ctx.path == '/logout') { return next(); } //================================================================ //Check authentication token to see if expired, but only if it's been a few minutes since last navigation if (stateMap.user.authenticated) { //This first bit sets the last nav in cases where it's never been set before //default to one hour ago in case it hasn't ever been set yet or isn't in statemap if (!stateMap.lastNav) { //Isn't this sketchy? Is this a date or a moment being set here stateMap.lastNav = moment().subtract(3600, 's').toDate();//60 minutes ago } var mNow = moment(new Date()); //todays date var mLastNav = moment(stateMap.lastNav); // another date var duration = moment.duration(mNow.diff(mLastNav)); var secondsSinceLastNav = duration.asSeconds(); if (secondsSinceLastNav > 300)//have we checked in the last 5 minutes? { if (tokenExpired()) { stateMap.user.authenticated = false; } } stateMap.lastNav = new Date(); } //=============================================================== //Not logged in and trying to go somewhere but authenticate? if (!stateMap.user.authenticated) { //hide nav $("#rf-nav").hide({ duration: 200 }); //page nav to authenticate if (ctx.path != '/authenticate/') return page('#!/authenticate/'); } else { //logged in so make sure to show toolbar here $("#rf-nav").show({ duration: 200 }); } next(); } //TODO: Clean up this coral reef steaming mess //replace with a function that generates these functions since they are all (nearly) identical var authenticate = function (ctx) { app.authenticate.configModule({ context: ctx }); app.authenticate.initModule(); } var reportData = function (ctx) { app.nav.setSelectedMenuItem('reportData'); app.reportData.configModule({ context: ctx }); app.reportData.initModule(); } var reportDataProdEmail = function (ctx) { app.nav.setSelectedMenuItem('reportData'); app.reportDataProdEmail.configModule({ context: ctx }); app.reportDataProdEmail.initModule(); } var reportDataExpires = function (ctx) { app.nav.setSelectedMenuItem('reportData'); app.reportDataExpires.configModule({ context: ctx }); app.reportDataExpires.initModule(); } var search = function (ctx) { app.nav.setSelectedMenuItem('search'); app.search.configModule({ context: ctx }); app.search.initModule(); } var customers = function (ctx) { app.nav.setSelectedMenuItem('customers'); app.customers.configModule({ context: ctx }); app.customers.initModule(); } var customerEdit = function (ctx) { app.nav.setSelectedMenuItem('customers'); app.customerEdit.configModule({ context: ctx }); app.customerEdit.initModule(); } var customerSites = function (ctx) { app.nav.setSelectedMenuItem('customers'); app.customerSites.configModule({ context: ctx }); app.customerSites.initModule(); } var customerSiteEdit = function (ctx) { app.nav.setSelectedMenuItem('customers'); app.customerSiteEdit.configModule({ context: ctx }); app.customerSiteEdit.initModule(); } var purchases = function (ctx) { app.nav.setSelectedMenuItem('customers'); app.purchases.configModule({ context: ctx }); app.purchases.initModule(); } var purchaseEdit = function (ctx) { app.nav.setSelectedMenuItem('customers'); app.purchaseEdit.configModule({ context: ctx }); app.purchaseEdit.initModule(); } var license = function (ctx) { app.nav.setSelectedMenuItem('license'); app.license.configModule({ context: ctx }); app.license.initModule(); } var licenseTemplates = function (ctx) { app.nav.setSelectedMenuItem('license'); app.licenseTemplates.configModule({ context: ctx }); app.licenseTemplates.initModule(); } var licenseRequests = function (ctx) { app.nav.setSelectedMenuItem('license'); app.licenseRequests.configModule({ context: ctx }); app.licenseRequests.initModule(); } var licenseRequestEdit = function (ctx) { app.nav.setSelectedMenuItem('license'); app.licenseRequestEdit.configModule({ context: ctx }); app.licenseRequestEdit.initModule(); } //case 3233 var licenses = function (ctx) { app.nav.setSelectedMenuItem('license'); app.licenses.configModule({ context: ctx }); app.licenses.initModule(); } //case 3233 var licenseView = function (ctx) { app.nav.setSelectedMenuItem('license'); app.licenseView.configModule({ context: ctx }); app.licenseView.initModule(); } var subscription = function (ctx) { app.nav.setSelectedMenuItem('subscription'); app.subscription.configModule({ context: ctx }); app.subscription.initModule(); } var subnotify = function (ctx) { app.nav.setSelectedMenuItem('subscription'); app.subnotify.configModule({ context: ctx }); app.subnotify.initModule(); } var templates = function (ctx) { app.nav.setSelectedMenuItem('templates'); app.templates.configModule({ context: ctx }); app.templates.initModule(); } var templateEdit = function (ctx) { app.nav.setSelectedMenuItem('templates'); app.templateEdit.configModule({ context: ctx }); app.templateEdit.initModule(); } var inbox = function (ctx) { app.nav.setSelectedMenuItem('inbox'); app.inbox.configModule({ context: ctx }); app.inbox.initModule(); } var mailEdit = function (ctx) { app.nav.setSelectedMenuItem('inbox'); app.mailEdit.configModule({ context: ctx }); app.mailEdit.initModule(); } var rfcases = function (ctx) { app.nav.setSelectedMenuItem('rfcases'); app.rfcases.configModule({ context: ctx }); app.rfcases.initModule(); } var rfcaseEdit = function (ctx) { app.nav.setSelectedMenuItem('rfcases'); app.rfcaseEdit.configModule({ context: ctx }); app.rfcaseEdit.initModule(); } var rfsettings = function (ctx) { app.nav.setSelectedMenuItem('rfsettings'); app.rfsettings.configModule({ context: ctx }); app.rfsettings.initModule(); } var ops = function (ctx) { app.nav.setSelectedMenuItem('ops'); app.ops.configModule({ context: ctx }); app.ops.initModule(); } //case 3233 var trials = function (ctx) { app.nav.setSelectedMenuItem('trials'); app.trials.configModule({ context: ctx }); app.trials.initModule(); } //case 3233 var trialEdit = function (ctx) { app.nav.setSelectedMenuItem('trials'); app.trialEdit.configModule({ context: ctx }); app.trialEdit.initModule(); } var notFound = function (ctx) { app.fourohfour.configModule({ context: ctx }); app.fourohfour.initModule(); } return { initModule: initModule, stateMap: stateMap }; //------------------- END PUBLIC METHODS --------------------- }());