]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/services/eframe.js
webstaff: Add height adjustment hacks for a couple dojo interfaces
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / services / eframe.js
1 angular.module('egCoreMod')
2
3 /*
4  * Iframe container for (mostly legacy) embedded interfaces
5  */
6 .directive('egEmbedFrame', function() {
7     return {
8         restrict : 'AE',
9         replace : true,
10         scope : {
11             // URL to load in the embed iframe
12             url : '=',
13
14             // optional hash of functions which augment or override 
15             // the stock xulG functions defined below.
16             handlers : '=',
17             frame : '=',
18
19             // called after onload of each new iframe page
20             onchange : '=',
21             saveSpace : '@',
22         },
23
24         templateUrl : './share/t_eframe',
25
26         link: function (scope, element, attrs) {
27             element.find('iframe').on(
28                 'load',
29                 function() {scope.egEmbedFrameLoader(this)}
30             );
31         },
32
33         controller : 
34                    ['$scope','$window','$location','$q','$timeout','egCore',
35             function($scope , $window , $location , $q , $timeout , egCore) {
36
37             $scope.save_space = $scope.saveSpace ? $scope.saveSpace : 300;
38             // Set the initial iframe height to just under the window height.
39             // leave room for the navbar, padding, margins, etc.
40             $scope.height = $window.outerHeight - $scope.save_space;
41
42             // browser client doesn't use cookies, so we don't load the
43             // (at the time of writing, quite limited) angular.cookies
44             // module.  We could load something, but this seems to work
45             // well enough for setting the auth cookie (at least, until 
46             // it doesn't).
47             //
48             // note: document.cookie is smart enough to leave unreferenced
49             // cookies alone, so contrary to how this might look, it's not 
50             // deleting other cookies (anoncache, etc.)
51             
52             // delete any existing ses cookie
53             $window.document.cookie = "ses=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
54             // push our authtoken in
55             $window.document.cookie = 'ses=' + egCore.auth.token() + '; path=/; secure'
56
57             // $location has functions for modifying paths and search,
58             // but they all assume you are staying within the angular
59             // app, which we are not.  Build the URLs by hand.
60             function open_tab(path) {
61                 var url = 'https://' + $window.location.hostname + 
62                     egCore.env.basePath + path;
63                 console.debug('egEmbedFrame opening tab ' + url);
64                 $window.open(url, '_blank').focus();
65             }
66
67             // define our own xulG functions to be inserted into the
68             // iframe.  NOTE: window-level functions are bad.  Though
69             // there is probably a way, I was unable to correctly wire
70             // up the iframe onload handler within the controller or link
71             // funcs.  In any event, the code below is meant as a stop-gap
72             // for porting dojo, etc. apps to angular apps and should
73             // eventually go away.
74             // NOTE: catalog integration is not a stop-gap
75
76             $scope.egEmbedFrameLoader = function(iframe) {
77
78                 $scope.frame = {dom:iframe};
79                 $scope.iframe = iframe;
80
81                 // Reset the iframe height to the final content height.
82                 $scope.height = $scope.iframe.contentWindow.document.body.scrollHeight;
83
84                 var page = $scope.iframe.contentWindow.location.href;
85                 console.debug('egEmbedFrameLoader(): ' + page);
86
87                 // reload ifram page w/o reloading the entire UI
88                 $scope.reload = function() {
89                     $scope.iframe.contentWindow.location.replace(
90                         $scope.iframe.contentWindow.location);
91                 }
92
93                 // tell the iframe'd window its inside the staff client
94                 $scope.iframe.contentWindow.IAMXUL = true;
95
96                 // also tell it it's inside the browser client, which 
97                 // may be needed in a few special cases.
98                 $scope.iframe.contentWindow.IAMBROWSER /* hear me roar */ = true; 
99
100                 // XUL has a dump() function which is occasinally called 
101                 // from embedded browsers.
102                 $scope.iframe.contentWindow.dump = function(msg) {
103                     console.debug('egEmbedFrame:dump(): ' + msg);
104                 }
105
106                 // Adjust the height again if the iframe loads the openils.Util Dojo module
107                 $timeout(function () {
108                     if ($scope.iframe.contentWindow.openils && $scope.iframe.contentWindow.openils.Util) {
109
110                         // HACK! for patron reg page
111                         var e = $scope.iframe.contentWindow.document.getElementById('myForm');
112                         var extra = 50;
113                         
114                         // HACK! for vandelay
115                         if (!e) {
116                             e = $scope.iframe.contentWindow.document.getElementById('vl-body-wrapper');
117                             extra = 50;
118                         }
119
120                         if (!e) {
121                             e = $scope.iframe.contentWindow.document.body;
122                             extra = 0;
123                         }
124
125                         $scope.iframe.contentWindow.openils.Util.addOnLoad( function() {
126                             var old_height = $scope.height;
127                             $scope.height = e.scrollHeight + extra;
128                             $scope.$apply();
129                         });
130                     }
131                 });
132
133                 // define a few commonly used stock xulG handlers. 
134                 
135                 $scope.iframe.contentWindow.xulG = {
136                     // patron search
137                     spawn_search : function(search) {
138                         open_tab('/circ/patron/search?search=' 
139                             + encodeURIComponent(js2JSON(search)));
140                     },
141
142                     // edit an existing user
143                     spawn_editor : function(info) {
144                         if (info.usr) {
145                             open_tab('/circ/patron/register/edit/' + info.usr);
146                         
147                         } else if (info.clone) {
148                             // FIXME: The save-and-clone operation in the
149                             // patron editor results in this action.  
150                             // For some reason, this specific function results
151                             // in a new browser window opening instead of a 
152                             // browser tab.  Possibly this is caused by the 
153                             // fact that the action occurs as a result of a
154                             // button click instead of an href.  *shrug*.
155                             // It's obnoxious.
156                             open_tab('/circ/patron/register/clone/' + info.clone);
157                         } 
158                     },
159
160                     // open a user account
161                     new_patron_tab : function(tab_info, usr_info) {
162                         open_tab('/circ/patron/' + usr_info.id + '/checkout');
163                     },
164
165                     get_barcode_and_settings_async : function(barcode, only_settings) {
166                         if (!barcode) return $q.reject();
167                         var deferred = $q.defer();
168
169                         var barcode_promise = $q.when(barcode);
170                         if (!only_settings) {
171
172                             // first verify / locate the barcode
173                             barcode_promise = egCore.net.request(
174                                 'open-ils.actor',
175                                 'open-ils.actor.get_barcodes',
176                                 egCore.auth.token(), 
177                                 egCore.auth.user().ws_ou(), 'actor', barcode
178                             ).then(function(resp) {
179
180                                 if (!resp || egCore.evt.parse(resp) || !resp.length) {
181                                     console.error('user not found: ' + barcode);
182                                     deferred.reject();
183                                     return null;
184                                 } 
185
186                                 resp = resp[0];
187                                 return barcode = resp.barcode;
188                             });
189                         }
190
191                         barcode_promise.then(function(barcode) {
192                             if (!barcode) return;
193
194                             return egCore.net.request(
195                                 'open-ils.actor',
196                                 'open-ils.actor.user.fleshed.retrieve_by_barcode',
197                                 egCore.auth.token(), barcode);
198
199                         }).then(function(user) {
200                             if (!user) return null;
201
202                             if (e = egCore.evt.parse(user)) {
203                                 console.error('user fetch failed : ' + e.toString());
204                                 deferred.reject();
205                                 return null;
206                             }
207
208                             // copied more or less directly from XUL menu.js
209                             var settings = {};
210                             for(var i = 0; i < user.settings().length; i++) {
211                                 settings[user.settings()[i].name()] = 
212                                     JSON2js(user.settings()[i].value());
213                             }
214
215                             if(!settings['opac.default_phone'] && user.day_phone()) 
216                                 settings['opac.default_phone'] = user.day_phone();
217                             if(!settings['opac.hold_notify'] && settings['opac.hold_notify'] !== '') 
218                                 settings['opac.hold_notify'] = 'email:phone';
219
220                             // Taken from patron/util.js format_name
221                             // FIXME: I18n
222                             var patron_name = 
223                                 ( user.prefix() ? user.prefix() + ' ' : '') +
224                                 user.family_name() + ', ' +
225                                 user.first_given_name() + ' ' +
226                                 ( user.second_given_name() ? user.second_given_name() + ' ' : '' ) +
227                                 ( user.suffix() ? user.suffix() : '');
228
229                             deferred.resolve({
230                                 "barcode": barcode, 
231                                 "settings" : settings, 
232                                 "user_email" : user.email(), 
233                                 "patron_name" : patron_name
234                             });
235                         });
236
237                         return deferred.promise;
238                     }
239                 }
240
241                 if ($scope.handlers) {
242                     $scope.handlers.reload = $scope.reload;
243                     angular.forEach($scope.handlers, function(val, key) {
244                         $scope.iframe.contentWindow.xulG[key] = val;
245                     });
246                 }
247
248                 if ($scope.onchange) $scope.onchange(page);
249             }
250         }]
251     }
252 })
253
254