]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/services/startup.js
LP1615805 No inputs after submit in patron search (AngularJS)
[Evergreen.git] / Open-ILS / web / js / ui / default / staff / services / startup.js
1 /**
2  * Core Service - egStartup
3  *
4  * Coordinates all startup routines and consolidates them into
5  * a single startup promise.  Startup can be launched from multiple
6  * controllers, etc., but only one startup routine will be run.
7  *
8  * If no valid authtoken is found, startup will exit early and 
9  * change the page href to the login page.  Otherwise, the global
10  * promise returned by startup.go() will be resolved after all
11  * async data is arrived.
12  */
13
14 angular.module('egCoreMod')
15
16 .config(['$locationProvider','$compileProvider',
17  function($locationProvider , $compileProvider) {
18     $locationProvider.html5Mode(true);
19     $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|mailto|blob):/);
20 }])
21
22 .factory('egStartup', 
23        ['$q','$rootScope','$location','$window','egIDL','egAuth','egEnv','egOrg',
24         '$cookies',
25 function($q,  $rootScope,  $location,  $window,  egIDL,  egAuth,  egEnv , egOrg ,
26          $cookies) {
27
28     var service = { promise : null }
29
30     // Some org settings affect every page.  Load them during startup.  
31     // Other startup data loaders can be added by appending to egEnv.loaders.
32     // egEnv.loaders functions must return a promise.
33     egEnv.loaders.push(
34         function() {
35             return egOrg.settings([
36                 'webstaff.format.dates',
37                 'webstaff.format.date_and_time',
38                 'ui.staff.max_recent_patrons', // affects navbar
39                 'ui.staff.traditional_catalog.enabled', // affects navbar
40                 'lib.timezone'
41             ]).then(
42                 function(set) {
43                     $rootScope.egDateFormat = 
44                         set['webstaff.format.dates'] || 'shortDate';
45                     $rootScope.egDateAndTimeFormat = 
46                         set['webstaff.format.date_and_time'] || 'short';
47
48                     // default to 1 for backwards compat.
49                     if (set['ui.staff.max_recent_patrons'] === null)
50                         set['ui.staff.max_recent_patrons'] = 1
51                 }
52             );
53         }
54     );
55
56     // returns true if we are staying on the current page
57     // false if we are redirecting to login
58     service.expiredAuthHandler = function(data) {
59         if (lf.isOffline) return true; // Only set by the offline UI
60
61         console.debug('egStartup.expiredAuthHandler()');
62
63         // Only notify other tabs the auth session has expired 
64         // when this tab was the first tab to know it.
65         // Note that there is a hole here: when the AngularJS
66         // login page is displayed again after a logout, there
67         // will be at least one more invocation of expiredAuthHandler
68         // by egStartup due to there being no authtoken - and this
69         // invocation will send a message on the eg.auth channel.
70         // However, because the AngularJS app doesn't start _listening_
71         // to the channel until the staff user has logged in, that
72         // second invocation has a much lower risk of causing
73         // a broadcast storm.
74         var broadcast = !(data && data.startedElsewhere);
75
76         egAuth.logout(broadcast); // clean up
77
78         // no need to redirect if we're on the /login page
79         if ($location.path() == '/login') return true;
80
81         // change locations to the login page, using the current page
82         // as the 'route_to' destination on /login
83         $window.location.href = $location
84             .path('/login')
85             .search({route_to : 
86                 $window.location.pathname + $window.location.search})
87             .absUrl();
88
89         return false;
90     }
91
92     // if during startup or any time in the future we encounter an expired
93     // authtoken, call our epired token handler
94     // we handle this here instead egAuth, since it affects the flow
95     // of the startup routines when no valid token exists during startup.
96     // Note that we need to ensure that we pass along the startedElsewhere
97     // flag, if available, to ensure that we don't start a broadcast storm
98     // on the eg.auth BroadcastChannel of any other tabs that happen to have
99     // the AngularJS staff client open.
100     $rootScope.$on('egAuthExpired', function(event, data) {service.expiredAuthHandler(data)});
101
102     // in case we just left an Angular context, clear the hold target
103     // and notify any open Angular catalog tabs to do the same
104     function clearHoldTarget() {
105         var patronHoldTarget = $cookies.get(
106             'eg.circ.patron_hold_target'
107         );
108         if (patronHoldTarget) {
109             $cookies.remove(
110                 'eg.circ.patron_hold_target'
111             )
112             if (typeof BroadcastChannel !== 'undefined') {
113                 var broadcaster = new BroadcastChannel(
114                     'eg.circ.patron_hold_target'
115                 );
116                 broadcaster.postMessage(
117                     { removedTarget: patronHoldTarget }
118                 );
119                 broadcaster.close();
120             }
121         }
122     }
123     clearHoldTarget();
124
125     service.go = function () {
126         if (service.promise) {
127             // startup already started, return our existing promise
128             return service.promise;
129         } 
130
131         // Apply the locale from the cookie before any network 
132         // calls are made.
133         var locale = $cookies.get('eg_locale');
134         if (locale) {
135             // Cookie is stored aa_bb.  OpenSRF wants aa-BB
136             var parts = locale.split(/_/);
137             OpenSRF.locale = parts[0] + '-' + parts[1].toUpperCase();
138             console.debug('Applying locale ' + OpenSRF.locale);
139         }
140
141         // create a new promise and fire off startup
142         var deferred = $q.defer();
143         service.promise = deferred.promise;
144
145         // IDL parsing is sync.  No promises required
146         egIDL.parseIDL();
147         egAuth.testAuthToken().then(
148
149             // testAuthToken resolved
150             function() { 
151                 egEnv.load().then(
152                     function() { deferred.resolve() }, 
153                     function() { 
154                         deferred.reject('egEnv did not resolve')
155                     }
156                 );
157             },
158
159             // testAuthToken rejected
160             function() { 
161                 console.log('egAuth found no valid authtoken');
162                 if (service.expiredAuthHandler()) deferred.resolve();
163             }
164         );
165
166         return service.promise;
167     }
168     
169     return service;
170 }]);
171