item status UI continued
authorBill Erickson <berick@esilibrary.com>
Fri, 16 May 2014 15:22:56 +0000 (11:22 -0400)
committerBill Erickson <berick@esilibrary.com>
Fri, 16 May 2014 15:22:56 +0000 (11:22 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/cat/item/index.tt2
Open-ILS/src/templates/staff/cat/item/summary_header.tt2
Open-ILS/src/templates/staff/cat/item/t_cat_pane.tt2
Open-ILS/src/templates/staff/cat/item/t_circs_pane.tt2
Open-ILS/src/templates/staff/cat/item/t_list.tt2
Open-ILS/src/templates/staff/cat/item/t_summary_pane.tt2
Open-ILS/src/templates/staff/cat/item/t_view.tt2
Open-ILS/src/templates/staff/css/style.css.tt2
Open-ILS/web/js/ui/default/staff/cat/item/app.js
Open-ILS/web/js/ui/default/staff/services/grid.js
Open-ILS/web/js/ui/default/staff/services/hatch.js

index 0ad87d7..4557afc 100644 (file)
@@ -10,6 +10,7 @@
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/cat/services/copy_details.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/cat/item/app.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/cat/services/record_html.js"></script>
 [% END %]
 
 <style>
@@ -31,7 +32,7 @@
 
         <!-- barcode input -->
         <input type="text" id="item-status-barcode" 
-          focus-me="focusBarcode" class="form-control" ng-model="args.barcode">
+          select-me="context.selectBarcode" class="form-control" ng-model="args.barcode">
 
         <!-- submit -->
         <input class="btn btn-default" 
   </div><!-- row -->
 </form>
 
+<div class="row">
+  <div class="col-md-6">
+    <div ng-show="context.itemNotFound" class="alert alert-danger">
+      [% l('Item Not Found') %]
+    </div>
+  </div>
+</div>
+
 <div ng-view></div>
 
 [% END %]
index 09d42cc..202c4b2 100644 (file)
@@ -1,5 +1,6 @@
 
-<div class="flex-container-striped flex-container-bordered">
+<div class="flex-container-striped flex-container-bordered"
+  ng-hide="context.itemNotFound">
   <div class="flex-row">
     <div class="flex-cell header-label">[% l('Title:') %]</div>
     <div class="flex-cell flex-2">
index f4cbcac..43436af 100644 (file)
@@ -1 +1,3 @@
-<h1>summary</h1>
+<h3>[% l('MARC Record') %]</h3>
+
+<eg-record-html record-id="recordId"></eg-record-html>
index bfad35b..17b8f79 100644 (file)
@@ -1,11 +1,13 @@
-<div class="col-md-12">
+<div class="col-md-6" ng-show="!prev_circ_summary">
+  <div class="alert alert-info">
+    [% l('No Previous Circ Group') %]
+  </div>
+</div>
+<div class="col-md-6" ng-show="prev_circ_summary">
   <div class="flex-row">
     <div class="flex-cell flex-2 header-label-big">
       [% l('Previous Circ Group') %]
     </div>
-    <div class="flex-cell flex-2 header-label-big">
-      [% l('Most Recent Circ Group') %]
-    </div>
   </div>
 
   <div class="flex-row">
           '{{prev_circ_usr.card().barcode()}}') %]
       </a>
     </div>
+  </div>
+
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Total Circs') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.num_circs()}}
+    </div>
+  </div>
+
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Checkout Date') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.start_time() | date:'short'}}
+    </div>
+  </div>
+
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Checkout Workstation') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.checkout_workstation()}}
+    </div>
+  </div>
+
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Last Renewed On') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.last_renewal_time() | date:'short'}}
+    </div>
+  </div>
+
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Renewal Workstation') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.last_renewal_workstation()}}
+    </div>
+  </div>
+
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Stop Fines Reason') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.last_stop_fines()}}
+    </div>
+  </div>
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Stop Fines Time') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.last_stop_fines_time() | date:'short'}}
+    </div>
+  </div>
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Checkin Time') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.last_checkin_time() | date:'short'}}
+    </div>
+  </div>
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Checkin Scan Time') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.last_checkin_scan_time() | date:'short'}}
+    </div>
+  </div>
+  <div class="flex-row">
+    <div class="flex-cell">[% l('Checkin Workstation') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{prev_circ_summary.last_checkin_workstation()}}
+    </div>
+  </div>
+</div>
+
+<div class="col-md-6" ng-show="!circ">
+  <div class="alert alert-info">
+    [% l('No Recent Circ Group') %]
+  </div>
+</div>
+<div class="col-md-6" ng-show="circ">
+  <div class="flex-row">
+    <div class="flex-cell flex-2 header-label-big">
+      [% l('Most Recent Circ Group') %]
+    </div>
+  </div>
+  <div class="flex-row">
     <div class="flex-cell">[% l('Patron') %]</div>
     <div class="flex-cell flex-cell-well">
       <a href="./circ/patron/{{circ.usr().id()}}/checkout" 
   <div class="flex-row">
     <div class="flex-cell">[% l('Total Circs') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.num_circs()}}
-    </div>
-    <div class="flex-cell">[% l('Total Circs') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ_summary.num_circs()}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Checkout Date') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.start_time() | date:'short'}}
-    </div>
-    <div class="flex-cell">[% l('Checkout Date') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ.xact_start() | date:'short'}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Checkout Workstation') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.checkout_workstation()}}
-    </div>
-    <div class="flex-cell">[% l('Checkout Workstation') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ.workstation().name()}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Last Renewed On') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.last_renewal_time() | date:'short'}}
-    </div>
-    <div class="flex-cell">[% l('Last Renewed On') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ_summary.last_renewal_time() | date:'short'}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Renewal Workstation') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.last_renewal_workstation()}}
-    </div>
-    <div class="flex-cell">[% l('Renewal Workstation') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ_summary.last_renewal_workstation()}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Stop Fines Reason') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.last_stop_fines()}}
-    </div>
-    <div class="flex-cell">[% l('Stop Fines Reason') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ.stop_fines()}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Stop Fines Time') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.last_stop_fines_time() | date:'short'}}
-    </div>
-    <div class="flex-cell">[% l('Stop Fines Time') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ.stop_fines_time() | date:'short'}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Checkin Time') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.last_checkin_time() | date:'short'}}
-    </div>
-    <div class="flex-cell">[% l('Checkin Time') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ.checkin_time() | date:'short'}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Checkin Scan Time') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.last_checkin_scan_time() | date:'short'}}
-    </div>
-    <div class="flex-cell">[% l('Checkin Scan Time') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ.checkin_scan_time() | date:'short'}}
     </div>
   </div>
   <div class="flex-row">
     <div class="flex-cell">[% l('Checkin Workstation') %]</div>
     <div class="flex-cell flex-cell-well">
-      {{prev_circ_summary.last_checkin_workstation()}}
-    </div>
-    <div class="flex-cell">[% l('Checkin Workstation') %]</div>
-    <div class="flex-cell flex-cell-well">
       {{circ.checkin_workstation.name()}}
     </div>
   </div>
index 8823659..d3fe261 100644 (file)
@@ -4,6 +4,7 @@
   features="-display,-sort,-multisort"
   main-label="[% l('Item Status') %]"
   items-provider="gridDataProvider"
+  on-item-retrieved="gridItemRetrieved"
   persist-key="cat.items">
 
   <eg-grid-field label="[% l('Barcode') %]"     path='barcode' visible></eg-grid-field>
index c16e191..21b2522 100644 (file)
@@ -7,8 +7,10 @@
     <div class="flex-cell">[% l('Circ Library') %]</div>
     <div class="flex-cell flex-cell-well">{{copy.circ_lib().shortname()}}</div>
 
-    <div class="flex-cell">[% l('Item Call #') %]</div>
-    <div class="flex-cell flex-cell-well">{{copy.call_number().label()}}</div>
+    <div class="flex-cell">[% l('Call # Prefix') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{copy.call_number().prefix().label()}}
+    </div>
 
     <div class="flex-cell">[% l('Status') %]</div>
     <div class="flex-cell flex-cell-well">{{copy.status().name()}}</div>
     <div class="flex-cell">[% l('Owning Library') %]</div>
     <div class="flex-cell flex-cell-well">{{copy.circ_lib().shortname()}}</div>
 
-    <div class="flex-cell">[% l('Renewal Type') %]</div>
-    <div class="flex-cell flex-cell-well">
-      <div ng-if="circ.opac_renewal() == 't'">[% l('OPAC') %]</div>
-      <div ng-if="circ.desk_renewal() == 't'">[% l('Desk') %]</div>
-      <div ng-if="circ.phone_renewal() == 't'">[% l('Phone') %]</div>
-    </div>
+    <div class="flex-cell">[% l('Call #') %]</div>
+    <div class="flex-cell flex-cell-well">{{copy.call_number().label()}}</div>
 
     <div class="flex-cell">[% l('Due Date') %]</div>
     <div class="flex-cell flex-cell-well">{{circ.due_date() | date:'short'}}</div>
     <div class="flex-cell">[% l('Copy Location') %]</div>
     <div class="flex-cell flex-cell-well">{{copy.location().name()}}</div>
 
-    <div class="flex-cell">[% l('Total Circs') %]</div>
-    <div class="flex-cell flex-cell-well">{{total_circs}}</div>
+    <div class="flex-cell">[% l('Call # Suffix') %]</div>
+    <div class="flex-cell flex-cell-well">
+      {{copy.call_number().suffix().label()}}
+    </div>
 
     <div class="flex-cell">[% l('Checkout Date') %]</div>
     <div class="flex-cell flex-cell-well">{{circ.xact_start() | date:'short'}}</div>
     <div class="flex-cell">[% l('Loan Duration') %]</div>
     <div class="flex-cell flex-cell-well">{{circ.duration()}}</div>
 
-    <div class="flex-cell">[% l('Total Circs - Current Year') %]</div>
-    <div class="flex-cell flex-cell-well">{{total_circs_this_year}}</div>
+    <div class="flex-cell">[% l('Renewal Type') %]</div>
+    <div class="flex-cell flex-cell-well">
+      <div ng-if="circ.opac_renewal() == 't'">[% l('OPAC') %]</div>
+      <div ng-if="circ.desk_renewal() == 't'">[% l('Desk') %]</div>
+      <div ng-if="circ.phone_renewal() == 't'">[% l('Phone') %]</div>
+    </div>
 
     <div class="flex-cell">[% l('Checkout Workstation') %]</div>
     <div class="flex-cell flex-cell-well">{{circ.workstation().name()}}</div>
@@ -69,8 +73,8 @@
     <div class="flex-cell">[% l('Fine Level') %]</div>
     <div class="flex-cell flex-cell-well">{{circ.duration_rule().name()}}</div>
 
-    <div class="flex-cell">[% l('Total Circs - Prev Year') %]</div>
-    <div class="flex-cell flex-cell-well">{{total_circs_prev_year}}</div>
+    <div class="flex-cell">[% l('Total Circs') %]</div>
+    <div class="flex-cell flex-cell-well">{{total_circs}}</div>
 
     <div class="flex-cell">[% l('Duration Rule') %]</div>
     <div class="flex-cell flex-cell-well">{{circ.duration_rule().name()}}</div>
@@ -83,8 +87,8 @@
     <div class="flex-cell">[% l('Reference') %]</div>
     <div class="flex-cell flex-cell-well">{{copy.ref()}}</div>
 
-    <div class="flex-cell">[% l('Renewal Workstation') %]</div>
-    <div class="flex-cell flex-cell-well">{{circ_summary.last_renewal_workstation()}}</div>
+    <div class="flex-cell">[% l('Total Circs - Current Year') %]</div>
+    <div class="flex-cell flex-cell-well">{{total_circs_this_year}}</div>
 
     <div class="flex-cell">[% l('Recurring Fine Rule') %]</div>
     <div class="flex-cell flex-cell-well">{{circ.recurring_fine_rule().name()}}</div>
     <div class="flex-cell">[% l('OPAC Visible') %]</div>
     <div class="flex-cell flex-cell-well">{{copy.opac_visible()}}</div>
 
-    <div class="flex-cell">[% l('Remaining Renewals') %]</div>
-    <div class="flex-cell flex-cell-well">{{circ.renewal_remaining()}}</div>
+    <div class="flex-cell">[% l('Total Circs - Prev Year') %]</div>
+    <div class="flex-cell flex-cell-well">{{total_circs_prev_year}}</div>
 
     <div class="flex-cell">[% l('Max Fine Rule') %]</div>
     <div class="flex-cell flex-cell-well">{{circ.max_fine_rule().name()}}</div>
     <div class="flex-cell">[% l('Holdable') %]</div>
     <div class="flex-cell flex-cell-well">{{copy.opac_visible()}}</div>
 
-    <!-- empty -->
-    <div class="flex-cell"></div>
-    <div class="flex-cell"></div>
+    <div class="flex-cell">[% l('Renewal Workstation') %]</div>
+    <div class="flex-cell flex-cell-well">{{circ_summary.last_renewal_workstation()}}</div>
 
     <div class="flex-cell">[% l('Checkin Time') %]</div>
     <div class="flex-cell flex-cell-well">
     <div class="flex-cell">[% l('Circulate') %]</div>
     <div class="flex-cell flex-cell-well">{{copy.circulate()}}</div>
 
-    <!-- empty -->
-    <div class="flex-cell"></div>
-    <div class="flex-cell"></div>
+    <div class="flex-cell">[% l('Remaining Renewals') %]</div>
+    <div class="flex-cell flex-cell-well">{{circ.renewal_remaining()}}</div>
 
     <div class="flex-cell">[% l('Checkin Scan Time') %]</div>
     <div class="flex-cell flex-cell-well">
index 3228700..124ff16 100644 (file)
@@ -6,24 +6,16 @@
 
 <ul class="nav nav-tabs">
   <li ng-class="{active : tab == 'summary'}">
-    <a href="./cat/item/view/{{copy.id()}}/summary">
-      [% l('Quick Summary') %]
-    </a>
+    <a href="./cat/item/{{copy.id()}}">[% l('Quick Summary') %]</a>
   </li>
   <li ng-class="{active : tab == 'circs'}">
-    <a href="./cat/item/view/{{copy.id()}}/circs">
-      [% l('Circulation History') %]
-    </a>
+    <a href="./cat/item/{{copy.id()}}/circs">[% l('Circulation History') %]</a>
   </li>
   <li ng-class="{active : tab == 'holds'}">
-    <a href="./cat/item/view/{{copy.id()}}/holds">
-      [% l('Holds / Transit') %]
-    </a>
+    <a href="./cat/item/{{copy.id()}}/holds">[% l('Holds / Transit') %]</a>
   </li>
   <li ng-class="{active : tab == 'cat'}">
-    <a href="./cat/item/view/{{copy.id()}}/cat">
-      [% l('Cataloging Info') %]
-    </a>
+    <a href="./cat/item/{{copy.id()}}/cat">[% l('Cataloging Info') %]</a>
   </li>
 </ul>
 <div class="tab-content">
index c4f1b7c..0c7c730 100644 (file)
 
 /* status bar along the bottom of the page ------------------------ */
 /* decrease padding to decrease overall height */
+
+/* bottom padding ensures no body content is hidden behind the status
+ * bar.  When content reaches the status bar a scroll bar appears */
+body { padding-bottom: 26px; }
+
 #status-bar {
   min-height:1.8em !important;
 }
index b229f78..690d01a 100644 (file)
@@ -18,7 +18,13 @@ angular.module('egItemStatus',
         resolve : resolver
     });
 
-    $routeProvider.when('/cat/item/view/:id/:tab', {
+    $routeProvider.when('/cat/item/:id', {
+        templateUrl: './cat/item/t_view',
+        controller: 'ViewCtrl',
+        resolve : resolver
+    });
+
+    $routeProvider.when('/cat/item/:id/:tab', {
         templateUrl: './cat/item/t_view',
         controller: 'ViewCtrl',
         resolve : resolver
@@ -41,7 +47,7 @@ function(egCore) {
         flesh : 3, 
         flesh_fields : {
             acp : ['call_number','location','status','location'],
-            acn : ['record'],
+            acn : ['record','prefix','suffix'],
             bre : ['simple_record','creator','editor']
         },
         select : { 
@@ -51,7 +57,7 @@ function(egCore) {
         } 
     }
 
-    service.fetch = function(barcode, id) {
+    service.fetch = function(barcode, id, noListDupes) {
         var promise;
 
         if (barcode) {
@@ -64,9 +70,18 @@ function(egCore) {
         return promise.then(function(copy) {
             if (!copy) return null;
 
-            var flatCopy = egCore.idl.toHash(copy, true);
-            flatCopy.index = service.index++;
-            service.copies.unshift(flatCopy);
+            var flatCopy;
+            if (noListDupes) {
+                // use the existing copy if possible
+                flatCopy = service.copies.filter(
+                    function(c) {return c.id == copy.id()})[0];
+            }
+
+            if (!flatCopy) {
+                flatCopy = egCore.idl.toHash(copy, true);
+                flatCopy.index = service.index++;
+                service.copies.unshift(flatCopy);
+            }
 
             return {
                 copy : copy, 
@@ -85,19 +100,19 @@ function(egCore) {
 .controller('SearchCtrl', 
        ['$scope','$location','egCore','egGridDataProvider','itemSvc',
 function($scope , $location , egCore , egGridDataProvider , itemSvc) {
-    $scope.focusBarcode = true;
+    $scope.args = {}; // search args
 
     // sub-scopes (search / detail-view) apply their version 
     // of retrieval function to $scope.context.search
     // and display toggling via $scope.context.toggleDisplay
-    $scope.context = {};
+    $scope.context = {
+        selectBarcode : true
+    };
 
     $scope.toggleView = function($event) {
         $scope.context.toggleDisplay();
         $event.preventDefault(); // avoid form submission
     }
-
-    $scope.args = {};
 }])
 
 /**
@@ -117,29 +132,34 @@ function($scope , $location , $timeout , egCore , egGridDataProvider , itemSvc)
     $scope.gridDataProvider = provider;
 
     $scope.context.search = function(args) {
+        $scope.context.itemNotFound = false;
         itemSvc.fetch(args.barcode).then(function(res) {
             if (res) {
                 provider.increment();
                 provider.selectOneItem(res.index);
+                $scope.args.barcode = '';
+            } else {
+                $scope.context.itemNotFound = true;
             }
+            $scope.context.selectBarcode = true;
         })
     }
 
-    if (itemSvc.copy) {
-        // If a copy was just displayed in the detail view, ensure it's
-        // focused in the list view.  However, give the grid a chance to
-        // instantiate before attempting to select any items.
-        $timeout(function() {
-            var flatCopy = itemSvc.copies.filter(
-                function(c) { return c.id == itemSvc.copy.id() })[0];
-            provider.selectOneItem(flatCopy.index);
-        });
-    }
+    // If a copy was just displayed in the detail view, ensure it's
+    // focused in the list view.
+    var selected = false;
+    $scope.gridItemRetrieved = function(item) {
+        if (selected || !itemSvc.copy) return;
+        if (itemSvc.copy.id() == item.id) {
+            provider.selectOneItem(item.index);
+            selected = true;
+        }
+    };
 
     $scope.context.toggleDisplay = function() {
         var item = provider.getSelectedItems()[0];
         if (item) 
-            $location.path('/cat/item/view/' + item.id + '/summary');
+            $location.path('/cat/item/' + item.id);
     }
 
 }])
@@ -148,23 +168,57 @@ function($scope , $location , $timeout , egCore , egGridDataProvider , itemSvc)
  * Detail view -- shows one copy
  */
 .controller('ViewCtrl', 
-       ['$scope','$location','$routeParams','egCore','itemSvc',
-function($scope , $location , $routeParams , egCore , itemSvc) {
+       ['$scope','$q','$location','$routeParams','egCore','itemSvc',
+function($scope , $q, $location , $routeParams , egCore , itemSvc) {
     var copyId = $routeParams.id;
-    $scope.tab = $routeParams.tab;
+    $scope.tab = $routeParams.tab || 'summary';
     $scope.context.page = 'detail';
 
     function loadCopy(barcode) {
+        $scope.context.itemNotFound = false;
+
+        // Avoid re-fetching the same copy while jumping tabs.
+        // In addition to being quicker, this helps to avoid flickering
+        // of the top panel which is always visible in the detail view.
+        //
+        // 'barcode' represents the loading of a new item - refetch it
+        // regardless of whether it matches the current item.
+        if (!barcode && itemSvc.copy && itemSvc.copy.id() == copyId) {
+            $scope.copy = itemSvc.copy;
+            $scope.recordId = itemSvc.copy.call_number().record().id();
+            return $q.when();
+        }
+
         delete $scope.copy;
         delete itemSvc.copy;
 
-        return itemSvc.fetch(barcode, copyId).then(function(res) {
-            if (!res) return;
+        var deferred = $q.defer();
+        itemSvc.fetch(barcode, copyId, true).then(function(res) {
+            $scope.context.selectBarcode = true;
+
+            if (!res) {
+                copyId = null;
+                $scope.context.itemNotFound = true;
+                deferred.reject(); // avoid propagation of data fetch calls
+                return;
+            }
+
             var copy = res.copy;
-            copyId = copy.id();
-            $scope.args.barcode = copy.barcode();
             itemSvc.copy = copy;
 
+            if (copyId && copyId != copy.id()) {
+                // if a new barcode is scanned in the detail view,
+                // update the url to match the ID of the new copy
+                $location.path('/cat/item/' + copy.id() + '/' + $scope.tab);
+                deferred.reject(); // avoid propagation of data fetch calls
+                return;
+            }
+
+            copyId = copy.id();
+            $scope.copy = copy;
+            $scope.recordId = copy.call_number().record().id();
+            $scope.args.barcode = '';
+
             // locally flesh org units
             copy.circ_lib(egCore.org.get(copy.circ_lib()));
             copy.call_number().owning_lib(
@@ -179,8 +233,10 @@ function($scope , $location , $routeParams , egCore , itemSvc) {
                 function(field) { copy[field](Boolean(copy[field]() == 't')) }
             );
 
-            $scope.copy = copy;
+            deferred.resolve();
         });
+
+        return deferred.promise;
     }
 
     // if loadPrev load the two most recent circulations
@@ -188,6 +244,7 @@ function($scope , $location , $routeParams , egCore , itemSvc) {
         delete $scope.circ;
         delete $scope.circ_summary;
         delete $scope.prev_circ_summary;
+        if (!copyId) return;
         
         egCore.pcrud.search('circ', 
             {target_copy : copyId},
@@ -246,6 +303,7 @@ function($scope , $location , $routeParams , egCore , itemSvc) {
         $scope.total_circs = 0;
         $scope.total_circs_this_year = 0;
         $scope.total_circs_prev_year = 0;
+        if (!copyId) return;
 
         egCore.pcrud.search('circbyyr', 
             {copy : copyId}, null, {atomic : true})
@@ -276,6 +334,7 @@ function($scope , $location , $routeParams , egCore , itemSvc) {
 
     function loadHolds() {
         delete $scope.hold;
+        if (!copyId) return;
 
         egCore.pcrud.search('ahr', 
             {   current_copy : copyId, 
@@ -303,6 +362,7 @@ function($scope , $location , $routeParams , egCore , itemSvc) {
     function loadTransits() {
         delete $scope.transit;
         delete $scope.hold_transit;
+        if (!copyId) return;
 
         egCore.pcrud.search('atc', 
             {target_copy : copyId},
@@ -335,19 +395,15 @@ function($scope , $location , $routeParams , egCore , itemSvc) {
         }
     }
 
+    $scope.context.toggleDisplay = function() {
+        $location.path('/cat/item/search');
+    }
+
     // handle the barcode scan box, which will replace our current copy
     $scope.context.search = function(args) {
-        // when searching by barcode, we have to wait for the 
-        // copy to arrive (to collect the copyID) before
-        // fetching the remaining tab data.
         loadCopy(args.barcode).then(loadTabData);
     }
 
-    $scope.context.toggleDisplay = function() {
-        $location.path('/cat/item/search');
-    }
-
-    loadCopy();
-    loadTabData();
+    loadCopy().then(loadTabData);
 }])
 
index 1c870f0..d3be787 100644 (file)
@@ -671,9 +671,9 @@ angular.module('egGridMod',
                 grid.dataProvider.get(grid.offset, grid.limit)
                 .then(null, null, function(item) {
                     if (item) {
+                        $scope.items.push(item)
                         if (grid.onItemRetrieved)
                             grid.onItemRetrieved(item);
-                        $scope.items.push(item)
                     }
                 });
             }
index 48d0e03..547cdf9 100644 (file)
@@ -467,6 +467,12 @@ angular.module('egCoreMod')
  * print media CSS to ensure this content (and not the rest
  * of the page) is printed.
  */
+
+// FIXME: only apply print CSS when print commands are issued via the 
+// print container, otherwise using the browser's native print page 
+// option will always result in empty pages.  Move the print CSS
+// out of the standalone CSS file and put it into a template file
+// for this directive.
 .directive('egPrintContainer', function() {
     return {
         restrict : 'AE',