initial tpac integration via eg-embed-frame
authorBill Erickson <berick@esilibrary.com>
Tue, 15 Jul 2014 19:48:29 +0000 (15:48 -0400)
committerBill Erickson <berick@esilibrary.com>
Tue, 15 Jul 2014 19:48:29 +0000 (15:48 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
12 files changed:
Open-ILS/src/templates/opac/parts/bookbag_actions.tt2
Open-ILS/src/templates/staff/cat/catalog/index.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/circ/patron/index.tt2
Open-ILS/src/templates/staff/circ/patron/register.tt2
Open-ILS/src/templates/staff/circ/patron/t_edit.tt2
Open-ILS/src/templates/staff/css/style.css.tt2
Open-ILS/src/templates/staff/navbar.tt2
Open-ILS/web/js/ui/default/opac/staff.js
Open-ILS/web/js/ui/default/staff/cat/catalog/app.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/circ/patron/register.js
Open-ILS/web/js/ui/default/staff/services/eframe.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/services/lframe.js [deleted file]

index de33841..611d1fc 100644 (file)
@@ -4,7 +4,7 @@
 
     # Wrap a url to open in a new tab in staff client.
     MACRO opac_wrap(url) BLOCK;
-         IF ctx.is_staff;
+         IF ctx.is_staff AND NOT ctx.is_browser_staff;
               # void(0) to return false and not go to new page in current tab.
               "javascript:xulG.new_tab(xulG.urls.XUL_OPAC_WRAPPER, {}, {'opac_url' : 'oils://remote" _ url _ "'});void(0);";
           ELSE;
diff --git a/Open-ILS/src/templates/staff/cat/catalog/index.tt2 b/Open-ILS/src/templates/staff/cat/catalog/index.tt2
new file mode 100644 (file)
index 0000000..61e4862
--- /dev/null
@@ -0,0 +1,15 @@
+[%
+  WRAPPER "staff/base.tt2";
+  ctx.page_title = l("Record Buckets"); 
+  ctx.page_app = "egCatalogApp";
+%]
+
+[% BLOCK APP_JS %]
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/eframe.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/cat/catalog/app.js"></script>
+[% END %]
+
+<div ng-view></div>
+
+[% END %]
+
index 4f38659..257462f 100644 (file)
@@ -9,7 +9,7 @@
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/grid.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/user.js"></script>
-<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/lframe.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/eframe.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/services/billing.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/services/circ.js"></script>
 [% INCLUDE 'staff/circ/share/circ_strings.tt2' %]
index 53505a1..4a3c9ce 100644 (file)
@@ -5,7 +5,7 @@
 %]
 
 [% BLOCK APP_JS %]
-<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/lframe.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/eframe.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/circ/patron/register.js"></script>
 <link rel="stylesheet" href="[% ctx.base_path %]/staff/css/circ.css" />
 [% END %]
index 379444a..26cc766 100644 (file)
@@ -1,3 +1,3 @@
 <!-- insert the patron registration UI -->
-<eg-legacy-frame url="patron_edit_url" handlers="funcs"></eg-legacy-frame>
+<eg-embed-frame url="patron_edit_url" handlers="funcs"></eg-embed-frame>
 
index 7d555a7..0a8becf 100644 (file)
@@ -169,7 +169,8 @@ table.list tr.selected td { /* deprecated? */
   white-space:nowrap;
 }
 
-.eg-legacy-frame {
+/* embedded UI iframe */
+.eg-embed-frame {
   width: 100%;
   border: none;
   margin: 0px;
index c4ff869..944958f 100644 (file)
         </a>
         <ul class="dropdown-menu">
           <li>
+            <a href="./cat/catalog/index" target="_self">
+              <span class="glyphicon glyphicon-search"></span>
+              [% l('Search the Catalog') %]
+            </a>
+          </li>
+          <li>
             <a href="./cat/bucket/record/view" target="_self">
               <span class="glyphicon glyphicon-list-alt"></span>
               [% l('Record Buckets') %]
index ebed5e5..adbfd97 100644 (file)
@@ -1,4 +1,11 @@
 /* staff client integration functions */
+
+// Browser staff client runs the TPAC within an iframe, whose onload
+// is not called until after the page onload is called. window.onload
+// actions are wrapped in timeouts (below) to ensure the wrapping page
+// has a chance to insert the necessary xulG, etc. functions into the
+// window.
+
 function debug(msg){dump(msg+'\n')}
 var eventCache={};
 function attachEvt(scope, name, action) {
@@ -120,21 +127,24 @@ function staff_hold_usr_barcode_changed(isload) {
 }
 window.onload = function() {
     // record details page events
-    var rec = location.href.match(/\/opac\/record\/(\d+)/);
-    if(rec && rec[1]) { 
-        runEvt('rdetail', 'recordRetrieved', rec[1]); 
-        runEvt('rdetail', 'MFHDDrawn');
-    }
-    if(location.href.match(/place_hold/)) {
-        // patron barcode may come from XUL or a CGI param
-        var patron_barcode = xulG.patron_barcode ||
-            document.getElementById('hold_usr_input').value;
-        if(patron_barcode) {
-            staff_hold_usr_barcode_changed(patron_barcode);
-        } else {
-            staff_hold_usr_barcode_changed(true);
+
+    setTimeout(function() {
+        var rec = location.href.match(/\/opac\/record\/(\d+)/);
+        if(rec && rec[1]) { 
+            runEvt('rdetail', 'recordRetrieved', rec[1]); 
+            runEvt('rdetail', 'MFHDDrawn');
         }
-    }
+        if(location.href.match(/place_hold/)) {
+            // patron barcode may come from XUL or a CGI param
+            var patron_barcode = xulG.patron_barcode ||
+                document.getElementById('hold_usr_input').value;
+            if(patron_barcode) {
+                staff_hold_usr_barcode_changed(patron_barcode);
+            } else {
+                staff_hold_usr_barcode_changed(true);
+            }
+        }
+    });
 }
 
 function rdetail_next_prev_actions(index, count, prev, next, start, end, results) {
@@ -167,6 +177,8 @@ function rdetail_next_prev_actions(index, count, prev, next, start, end, results
     ol = window.onload;
     window.onload = function() {
         if(ol) ol(); 
-        runEvt('rdetail', 'nextPrevDrawn', Number(index), Number(count)); 
+        setTimeout(function() {
+            runEvt('rdetail', 'nextPrevDrawn', Number(index), Number(count)); 
+        });
     };
 }
diff --git a/Open-ILS/web/js/ui/default/staff/cat/catalog/app.js b/Open-ILS/web/js/ui/default/staff/cat/catalog/app.js
new file mode 100644 (file)
index 0000000..99ce5f7
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * TPAC Frame App
+ */
+
+angular.module('egCatalogApp', ['ui.bootstrap','ngRoute','egCoreMod'])
+
+.config(function($routeProvider, $locationProvider, $compileProvider) {
+    $locationProvider.html5Mode(true);
+    $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export
+
+    var resolver = {delay : 
+        ['egStartup', function(egStartup) {return egStartup.go()}]}
+
+    $routeProvider.when('/cat/catalog/index', {
+        template: '<eg-embed-frame url="catalog_url" handlers="handlers"></eg-embed-frame>',
+        controller: 'CatalogCtrl',
+        resolve : resolver
+    });
+
+    $routeProvider.otherwise({redirectTo : '/cat/catalog/index'});
+})
+
+
+/**
+ * */
+.controller('CatalogCtrl',
+       ['$scope','$routeParams','$location','egCore',
+function($scope , $routeParams , $location , egCore) {
+
+    // TODO: is start path configurable in the xul client?
+    var url = $location.absUrl().replace(/\/staff.*/, '/opac/advanced');
+
+    // pass the reg URL into the scope, thus into the 
+    $scope.catalog_url = url;
+
+    $scope.handlers = {};
+}])
index a74b023..13b4a41 100644 (file)
@@ -15,25 +15,25 @@ angular.module('egPatronRegApp', ['ui.bootstrap','ngRoute','egCoreMod'])
         ['egStartup', function(egStartup) {return egStartup.go()}]}
 
     $routeProvider.when('/circ/patron/register', {
-        template: '<eg-legacy-frame url="reg_url"></eg-legacy-frame>',
+        template: '<eg-embed-frame url="reg_url"></eg-embed-frame>',
         controller: 'PatronRegCtrl',
         resolve : resolver
     });
 
     $routeProvider.when('/circ/patron/register/stage/:stage_username', {
-        template: '<eg-legacy-frame url="reg_url"></eg-legacy-frame>',
+        template: '<eg-embed-frame url="reg_url"></eg-embed-frame>',
         controller: 'PatronRegCtrl',
         resolve : resolver
     });
 
     $routeProvider.when('/circ/patron/register/edit/:edit_id', {
-        template: '<eg-legacy-frame url="reg_url"></eg-legacy-frame>',
+        template: '<eg-embed-frame url="reg_url"></eg-embed-frame>',
         controller: 'PatronRegCtrl',
         resolve : resolver
     });
 
     $routeProvider.when('/circ/patron/register/clone/:clone_id', {
-        template: '<eg-legacy-frame url="reg_url"></eg-legacy-frame>',
+        template: '<eg-embed-frame url="reg_url"></eg-embed-frame>',
         controller: 'PatronRegCtrl',
         resolve : resolver
     });
@@ -45,8 +45,8 @@ angular.module('egPatronRegApp', ['ui.bootstrap','ngRoute','egCoreMod'])
 /**
  * */
 .controller('PatronRegCtrl',
-       ['$scope','$routeParams','$location','$filter','egCore',
-function($scope , $routeParams , $location , $filter , egCore) {
+       ['$scope','$routeParams','$location','egCore',
+function($scope , $routeParams , $location , egCore) {
     
 
     var url = $location.absUrl().replace(/\/staff.*/, '/actor/user/register');
diff --git a/Open-ILS/web/js/ui/default/staff/services/eframe.js b/Open-ILS/web/js/ui/default/staff/services/eframe.js
new file mode 100644 (file)
index 0000000..fa5207e
--- /dev/null
@@ -0,0 +1,123 @@
+angular.module('egCoreMod')
+
+/*
+ * Iframe container for (mostly legacy) embedded interfaces
+ */
+.directive('egEmbedFrame', function() {
+    return {
+        restrict : 'AE',
+        replace : true,
+        scope : {
+            // URL to load in the embed iframe
+            url : '=',
+
+            // optional hash of functions which augment or override 
+            // the stock xulG functions defined below.
+            handlers : '='
+        },
+
+        template : '<iframe src="{{url}}" onload="egEmbedFrameLoader(this)" '
+            + 'class="eg-embed-frame" style="height:{{height}}px"></iframe>',
+
+        controller : 
+                   ['$scope','$window','$location','egCore',
+            function($scope , $window , $location , egCore) {
+
+            // Set the iframe height to just under the window height.
+            // leave room for the navbar, padding, margins, etc.
+            $scope.height = $window.outerHeight - 250;
+
+            // browser client doesn't use cookies, so we don't load the
+            // (at the time of writing, quite limited) angular.cookies
+            // module.  We could load something, but this seems to work
+            // well enough for setting the auth cookie (at least, until 
+            // it doesn't).
+            //
+            // note: document.cookie is smart enough to leave unreferenced
+            // cookies alone, so contrary to how this might look, it's not 
+            // deleting other cookies (anoncache, etc.)
+            
+            // delete any existing ses cookie
+            $window.document.cookie = "ses=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
+            // push our authtoken in
+            $window.document.cookie = 'ses=' + egCore.auth.token() + '; path=/; secure'
+
+            // $location has functions for modifying paths and search,
+            // but they all assume you are staying within the angular
+            // app, which we are not.  Build the URLs by hand.
+            function open_tab(path) {
+                var url = 'https://' + $window.location.hostname + 
+                    egCore.env.basePath + path;
+                console.debug('egEmbedFrame opening tab ' + url);
+                $window.open(url, '_blank').focus();
+            }
+
+            // define our own xulG functions to be inserted into the
+            // iframe.  NOTE: window-level functions are bad.  Though
+            // there is probably a way, I was unable to correctly wire
+            // up the iframe onload handler within the controller or link
+            // funcs.  In any event, the code below is meant as a stop-gap
+            // for porting dojo, etc. apps to angular apps and should
+            // eventually go away.
+            // NOTE: catalog integration is not a stop-gap
+            $window.egEmbedFrameLoader = function(iframe) {
+
+                console.debug('egEmbedFrameLoader()...');
+
+                // tell the iframe'd window its inside the staff client
+                iframe.contentWindow.IAMXUL = true;
+
+                // also tell it it's inside the browser client, which 
+                // may be needed in a few special cases.
+                iframe.contentWindow.IAMBROWSER /* hear me roar */ = true; 
+
+                // XUL has a dump() function which is occasinally called 
+                // from embedded browsers.
+                iframe.contentWindow.dump = function(msg) {
+                    console.debug('egEmbedFrame:dump(): ' + msg);
+                }
+
+                // define a few commonly used stock xulG handlers. 
+                
+                iframe.contentWindow.xulG = {
+                    // patron search
+                    spawn_search : function(search) {
+                        open_tab('/circ/patron/search?search=' 
+                            + encodeURIComponent(js2JSON(search)));
+                    },
+
+                    // edit an existing user
+                    spawn_editor : function(info) {
+                        if (info.usr) {
+                            open_tab('/circ/patron/register/edit/' + info.usr);
+                        
+                        } else if (info.clone) {
+                            // FIXME: The save-and-clone operation in the
+                            // patron editor results in this action.  
+                            // For some reason, this specific function results
+                            // in a new browser window opening instead of a 
+                            // browser tab.  Possibly this is caused by the 
+                            // fact that the action occurs as a result of a
+                            // button click instead of an href.  *shrug*.
+                            // It's obnoxious.
+                            open_tab('/circ/patron/register/clone/' + info.clone);
+                        } 
+                    },
+
+                    // open a user account
+                    new_patron_tab : function(tab_info, usr_info) {
+                        open_tab('/circ/patron/' + usr_info.id + '/checkout');
+                    }  
+                }
+
+                if ($scope.handlers) {
+                    angular.forEach($scope.handlers, function(val, key) {
+                        iframe.contentWindow.xulG[key] = val;
+                    });
+                }
+            }
+        }]
+    }
+})
+
+
diff --git a/Open-ILS/web/js/ui/default/staff/services/lframe.js b/Open-ILS/web/js/ui/default/staff/services/lframe.js
deleted file mode 100644 (file)
index 26adcdd..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-angular.module('egCoreMod')
-
-/*
- * Iframe container for legacy embedded interfaces
- */
-.directive('egLegacyFrame', function() {
-    return {
-        restrict : 'AE',
-        replace : true,
-        scope : {
-            // URL to load in the legacy iframe
-            url : '=',
-
-            // optional hash of functions which augment or override 
-            // the stock xulG functions defined below.
-            handlers : '='
-        },
-
-        template : '<iframe src="{{url}}" onload="egLegacyFrameLoader(this)" '
-            + 'class="eg-legacy-frame" style="height:{{height}}px"></iframe>',
-
-        controller : 
-                   ['$scope','$window','$location','egCore',
-            function($scope , $window , $location , egCore) {
-
-            // Set the iframe height to just under the window height.
-            // leave room for the navbar, padding, margins, etc.
-            $scope.height = $window.outerHeight - 250;
-
-            // $location has functions for modifying paths and search,
-            // but they all assume you are staying within the angular
-            // app, which we are not.  Build the URLs by hand.
-            function open_tab(path) {
-                var url = 'https://' + $window.location.hostname + 
-                    egCore.env.basePath + path;
-                console.debug('egLegacyFrame opening tab ' + url);
-                $window.open(url, '_blank').focus();
-            }
-
-            // define our own xulG functions to be inserted into the
-            // iframe.  NOTE: window-level functions are bad.  Though
-            // there is probably a way, I was unable to correctly wire
-            // upda the iframe onload handler within the 
-            // way.  In any event, the code below is meant as a stop-gap
-            // for porting dojo, etc. apps to angular apps and should
-            // eventually go away.
-            $window.egLegacyFrameLoader = function(iframe) {
-
-                // tell the iframe'd window its inside the staff client
-                iframe.contentWindow.IAMXUL = true;
-
-                // also tell it it's inside the browser client, which 
-                // may be needed in a few special cases.
-                iframe.contentWindow.IAMBROWSER = true;
-
-                // define a few commonly used stock xulG handlers. 
-                
-                iframe.contentWindow.xulG = {
-                    // patron search
-                    spawn_search : function(search) {
-                        open_tab('/circ/patron/search?search=' 
-                            + encodeURIComponent(js2JSON(search)));
-                    },
-
-                    // edit an existing user
-                    spawn_editor : function(info) {
-                        if (info.usr) {
-                            open_tab('/circ/patron/register/edit/' + info.usr);
-                        
-                        } else if (info.clone) {
-                            // FIXME: The save-and-clone operation in the
-                            // patron editor results in this action.  
-                            // For some reason, this specific function results
-                            // in a new browser window opening instead of a 
-                            // browser tab.  Possibly this is caused by the 
-                            // fact that the action occurs as a result of a
-                            // button click instead of an href.  *shrug*.
-                            // It's obnoxious.
-                            open_tab('/circ/patron/register/clone/' + info.clone);
-                        } 
-                    },
-
-                    // open a user account
-                    new_patron_tab : function(tab_info, usr_info) {
-                        open_tab('/circ/patron/' + usr_info.id + '/checkout');
-                    }  
-                }
-
-                if ($scope.handlers) {
-                    angular.forEach($scope.handlers, function(val, key) {
-                        iframe.contentWindow.xulG[key] = val;
-                    });
-                }
-            }
-        }]
-    }
-})
-
-