/* * 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("/ravLicenses/:id/:cust_id", ravLicenses); page("/ravLicense/:id/:cust_id", ravLicense); 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 trialEdit = function (ctx) { app.nav.setSelectedMenuItem("trials"); app.trialEdit.configModule({ context: ctx }); app.trialEdit.initModule(); }; var ravLicense = function (ctx) { app.nav.setSelectedMenuItem("customers"); app.ravLicense.configModule({ context: ctx }); app.ravLicense.initModule(); }; var ravLicenses = function (ctx) { app.nav.setSelectedMenuItem("customers"); app.ravLicenses.configModule({ context: ctx }); app.ravLicenses.initModule(); }; var notFound = function (ctx) { app.fourohfour.configModule({ context: ctx }); app.fourohfour.initModule(); }; return { initModule: initModule, stateMap: stateMap }; //------------------- END PUBLIC METHODS --------------------- })();