ff and ui : fulfillment_admin perm; paging improvements
authorBill Erickson <berick@esilibrary.com>
Mon, 28 Oct 2013 19:57:52 +0000 (15:57 -0400)
committerBill Erickson <berick@esilibrary.com>
Mon, 28 Oct 2013 19:57:52 +0000 (15:57 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/sql/Pg/fulfillment-mods.sql
Open-ILS/src/templates/staff/fulfillment/t_actions.tt2
Open-ILS/web/js/ui/default/staff/fulfillment/app.js

index aaaa85b..7d70751 100644 (file)
@@ -114,6 +114,15 @@ CREATE TRIGGER bre_load_item_tgr AFTER INSERT ON biblio.record_entry
 
 -- SEED DATA -----------------------------------------------------------------
 
+-- note: we can't pin a well-known ID, because it will eventually get so
+-- i18n is not represented yet.
+INSERT INTO permission.perm_list (code, description)
+VALUES (
+    'FULFILLMENT_ADMIN',
+    'Allows administration of fulfillment transactions'
+);
+
+
 INSERT INTO action_trigger.hook (key,core_type,description,passive) 
     VALUES ('refresh_timeout.bre','bre','Bib record needs to be refreshed',TRUE);
 INSERT INTO action_trigger.hook (key,core_type,description,passive) 
index 64674a0..6d9c3ba 100644 (file)
@@ -1,10 +1,20 @@
 <div class="btn-group text-left">
-  <button type="button" class="btn btn-default" ng-class="{disabled : action_pending}"
+
+  <!-- first page -->
+  <button type="button" class="btn btn-default" 
+    ng-class="{disabled : action_pending}"
     ng-show="itemList.offset" ng-click="firstPage()">Start</button>
-  <button type="button" class="btn btn-default" ng-class="{disabled : action_pending}"
+
+  <!-- previous page -->
+  <button type="button" class="btn btn-default" 
+    ng-class="{disabled : action_pending}"
     ng-show="itemList.offset" ng-click="prevPage()">&laquo;</button>
-  <button type="button" class="btn btn-default" ng-class="{disabled : action_pending}"
+
+  <!-- next page -->
+  <button type="button" class="btn btn-default" 
+    ng-class="{disabled : action_pending}"
     ng-click="nextPage()">&raquo;</button>
+
   <div class="btn-group">
     <button type="button" class="btn btn-default dropdown-toggle" 
         ng-class="{disabled : action_pending}" data-toggle="dropdown">
index 0a5dde8..11da6e2 100644 (file)
@@ -51,6 +51,7 @@ angular.module('ffMain', ['ngRoute', 'egCoreMod', 'egUiMod', 'egUserMod'])
 
 /**
  * Data shared across FF controllers.
+ * TODO: this call all live in FFMainCtrl
  */
 .factory('ffService', 
 ['$rootScope', 'egOrg', 'egAuth', 
@@ -97,12 +98,8 @@ function ($scope, $route, egStartup, ffService, egAuth, egUser) {
     egStartup.go().then(function() {
         // after startup, we want to fetch the perm orgs for our 
         // logged in user.  From there, we can drive the org selector
-        // TODO: we need an FF-specific perm, since login perms are 
-        // all or none.
-        egUser.hasPermAt('STAFF_LOGIN') 
+        egUser.hasPermAt('FULFILLMENT_ADMIN') 
         .then(function(orgList) {
-            console.log('setting login list at ' + 
-                orgList.map(function(org) { return org.shortname() }));
             ffService.orgList(orgList);
             $scope.ffService = ffService;
         });
@@ -508,13 +505,37 @@ function ($scope, $q, $compile, $timeout, $rootScope, $location,
             };
         }
     );
+
+    // data collection and pagination
+    
+    // collector function collects the list of items
+    // and calls itemList.addItem for each one.
+    $scope.setCollector = function(colFn) {
+        $scope.collector = colFn;
+    }
+
+    $scope.firstPage = function() {
+        $scope.itemList.offset = 0;
+        $scope.collector();
+    };
+
+    $scope.nextPage = function() {
+        $scope.itemList.offset += $scope.itemList.limit;
+        $scope.collector();
+    };
+
+    $scope.prevPage = function() {
+        $scope.itemList.offset -= $scope.itemList.limit;
+        $scope.collector();
+    };
+
 }])
 
 .controller('TransitsCtrl',
 ['$scope', '$q', 'egPCRUD', 'ffService',
 function ($scope, $q, egPCRUD, ffService) {
 
-    $scope.drawTable = function() {
+    $scope.setCollector(function() {
         var deferred = $q.defer();
         $scope.itemList.items = [];
 
@@ -552,7 +573,8 @@ function ($scope, $q, egPCRUD, ffService) {
             {   limit : $scope.itemList.limit,
                 offset : $scope.itemList.offset,
                 flesh : 1, 
-                flesh_fields : {atc : ['target_copy']}
+                flesh_fields : {atc : ['target_copy']},
+                order_by : {'atc' : 'source_send_time, id'}
             }, {atomic : true}
         ).then(function(transits) {
             angular.forEach(transits, function(transit) {
@@ -560,17 +582,16 @@ function ($scope, $q, egPCRUD, ffService) {
                   {barcode : transit.target_copy().barcode()});
             });
         });
-    };
+    });
     
-    // outbound tab defaults to lender view
-    return $scope.drawTable($scope.tab_outbound == true);
+    return $scope.collector();
 }])
 
 .controller('CircCtrl',
 ['$scope', '$q', 'egPCRUD', 'ffService',
 function ($scope, $q, egPCRUD, ffService) {
 
-    $scope.drawTable = function() {
+    $scope.setCollector(function() {
         var deferred = $q.defer();
         $scope.itemList.items = [];
 
@@ -606,7 +627,8 @@ function ($scope, $q, egPCRUD, ffService) {
             {   limit : $scope.itemList.limit,
                 offset : $scope.itemList.offset,
                 flesh : 1, 
-                flesh_fields : {circ : ['target_copy']}
+                flesh_fields : {circ : ['target_copy']},
+                order_by : {'circ' : 'xact_start, id'}
             }, {atomic : true}
         ).then(function(circs) {
             angular.forEach(circs, function(circ) {
@@ -614,10 +636,10 @@ function ($scope, $q, egPCRUD, ffService) {
                   {barcode : circ.target_copy().barcode()});
             });
         });
-    };
+    });
     
     // outbound tab defaults to lender view
-    return $scope.drawTable();
+    return $scope.collector();
 }])
 
 
@@ -851,13 +873,12 @@ function($scope, $q, $http, ffService, formDataObject, egAuth) {
             headers: {'Content-Type': 'multipart/form-data'}
         })
         .success(function(data, status, headers, config) {
-            console.log("upload finished");
             $scope.in_flight = false;
             $scope.uploadComplete = true;
             deferred.resolve(data);
         })
         .error(function(data, status, headers, config){
-            console.warn("upload failed");
+            console.warn("upload failed: " + status);
             $scope.in_flight = false;
             $scope.uploadFailed = true;
             deferred.reject(status);