in-house-use UI
authorBill Erickson <berick@esilibrary.com>
Tue, 13 May 2014 19:54:08 +0000 (15:54 -0400)
committerBill Erickson <berick@esilibrary.com>
Tue, 13 May 2014 19:54:08 +0000 (15:54 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
Open-ILS/src/templates/staff/circ/in_house_use/index.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/navbar.tt2
Open-ILS/web/js/ui/default/staff/circ/in_house_use/app.js [new file with mode: 0644]

diff --git a/Open-ILS/src/templates/staff/circ/in_house_use/index.tt2 b/Open-ILS/src/templates/staff/circ/in_house_use/index.tt2
new file mode 100644 (file)
index 0000000..6b87db2
--- /dev/null
@@ -0,0 +1,79 @@
+[%
+  WRAPPER "staff/base.tt2";
+  ctx.page_title = l("In-House Use"); 
+  ctx.page_app = "egInHouseUseApp";
+  ctx.page_ctrl = "InHouseUseCtrl";
+%]
+
+[% BLOCK APP_JS %]
+<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/circ/in_house_use/app.js"></script>
+[% END %]
+
+<style>
+  /* FIXME: MOVE ME */
+  #in-house-use-barcode {width: 16em;}
+  #in-house-use-form { margin-bottom: 20px }
+</style>
+
+<form id="in-house-use-form" ng-submit="checkout(args)" role="form">
+  <div class="row">
+
+    <div class="col-md-2">
+      <div class="input-group">
+        <label class="input-group-addon" for="in-house-num-uses">
+          [% l('# of Uses:') %]
+        </label>
+        <input type="number" min="1" max="{{countMax}}"
+          class="form-control" focus-me="useFocus"
+           id="in-house-num-uses" ng-model="args.num_uses"/>
+      </div>
+    </div>
+
+    <div class="col-md-10">
+
+      <div class="input-group">
+        <div class="input-group-btn" dropdown>
+          <button type="button" class="btn btn-default dropdown-toggle">
+            {{selectedNcType() || "[% l('Barcode') %]"}}
+            <span class="caret"></span>
+          </button>
+          <ul class="dropdown-menu">
+            <li><a href dropdown-toggle
+              ng-click="args.noncat_type='barcode';bcFocus=true">
+              [% l('Barcode') %]</a>
+            </li>
+            <li class="divider"></li>
+            <li><a href dropdown-toggle
+              ng-repeat='type in nonCatTypes'
+              ng-click="args.noncat_type=type.id()">{{type.name()}}</a>
+            </li>
+          </ul>
+        </div>
+
+        <input type="text" id="in-house-use-barcode" focus-me="bcFocus"
+          class="form-control" ng-model="args.barcode"
+          ng-disabled="args.noncat_type != 'barcode'"/>
+        <input class="btn btn-default" type="submit" value="[% l('Submit') %]"/>
+      </div>
+
+    </div><!-- col -->
+  </div><!-- row -->
+</form>
+
+<eg-grid
+  id-field="index"
+  features="-display,-sort,-multisort"
+  main-label="[% l('In-House Use') %]"
+  items-provider="gridDataProvider"
+  persist-key="circ.in_house_use">
+  <eg-grid-field label="[% l('# of Uses') %]"   path='num_uses' visible></eg-grid-field>
+  <eg-grid-field label="[% l('Barcode') %]"     path='copy.barcode' visible></eg-grid-field>
+  <eg-grid-field label="[% l('Call Number') %]" path="copy.call_number.label" visible></eg-grid-field>
+  <eg-grid-field label="[% l('Location') %]"    path="copy.location.name" visible></eg-grid-field>
+  <eg-grid-field label="[% l('Title') %]"       path="title" visible></eg-grid-field>
+</eg-grid>
+
+[% END %]
index c2de8b8..db4ffc9 100644 (file)
               <span>[% l('Verify Credentials') %]</span>
             </a>
           </li>
+          <li>
+            <a href="./circ/in_house_use/index" target="_self">
+              <span class="glyphicon glyphicon-pencil"></span>
+              <span>[% l('Record In-House Use') %]</span>
+            </a>
+          </li>
         </ul>
       </li>
 
diff --git a/Open-ILS/web/js/ui/default/staff/circ/in_house_use/app.js b/Open-ILS/web/js/ui/default/staff/circ/in_house_use/app.js
new file mode 100644 (file)
index 0000000..5f7723e
--- /dev/null
@@ -0,0 +1,117 @@
+angular.module('egInHouseUseApp', 
+    ['ngRoute', 'egCoreMod', 'egUiMod', 'egGridMod'])
+
+.config(function($routeProvider, $locationProvider, $compileProvider) {
+    $locationProvider.html5Mode(true);
+    $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export
+
+
+})
+
+.controller('InHouseUseCtrl',
+       ['$scope','egCore','egGridDataProvider','egConfirmDialog',
+function($scope,  egCore,  egGridDataProvider , egConfirmDialog) {
+
+    var countCap;
+    var countMax;
+
+    egCore.startup.go().then(function() {
+
+        // grab our non-cat types after startup
+        egCore.pcrud.search('cnct', 
+            {owning_lib : 
+                egCore.org.fullPath(egCore.auth.user().ws_ou(), true)},
+            null, {atomic : true}
+        ).then(function(list) { 
+            egCore.env.absorbList(list, 'cnct');
+            $scope.nonCatTypes = list 
+        });
+
+        // org settings for max and warning in-house-use counts
+        
+        egCore.org.settings([
+            'ui.circ.in_house_use.entry_cap',
+            'ui.circ.in_house_use.entry_warn'
+        ]).then(function(set) {
+            countWarn = set['ui.circ.in_house_use.entry_warn'] || 20;
+            $scope.countMax = countMax = 
+                set['ui.circ.in_house_use.entry_cap'] || 99;
+        });
+    });
+
+    $scope.useFocus = true;
+    $scope.args = {noncat_type : 'barcode', num_uses : 1};
+    var checkouts = [];
+
+    var provider = egGridDataProvider.instance({});
+    provider.get = function(offset, count) {
+        return provider.arrayNotifier(checkouts, offset, count);
+    }
+
+    provider.itemFieldValue = provider.nestedItemFieldValue;
+    $scope.gridDataProvider = provider;
+
+    // currently selected non-cat type
+    $scope.selectedNcType = function() {
+        if (!egCore.env.cnct) return null; // too soon
+        var type = egCore.env.cnct.map[$scope.args.noncat_type];
+        return type ? type.name() : null;
+    }
+
+    $scope.checkout = function(args) {
+        var coArgs = {
+            count : args.num_uses,
+            'location' : egCore.auth.user().ws_ou()
+        };
+
+        if (args.noncat_type == 'barcode') {
+
+            egCore.pcrud.search('acp',
+                {barcode : args.barcode, deleted : 'f'},
+                {   flesh : 3, 
+                    flesh_fields : {
+                        acp : ['call_number','location'],
+                        acn : ['record'],
+                        bre : ['simple_record']
+                    },
+                    select : { bre : ['id'] } // avoid fleshing MARC
+                }
+            ).then(null, null, function(copy) {
+                coArgs.copyid = copy.id();
+
+                performCheckout(
+                    'open-ils.circ.in_house_use.create',
+                    coArgs, {copy:copy}
+                );
+            });
+
+        } else {
+            coArgs.non_cat_type = args.noncat_type;
+            performCheckout(
+                'open-ils.circ.non_cat_in_house_use.create',
+                coArgs, {title : $scope.selectedNcType()}
+            );
+        }
+    }
+
+    function performCheckout(method, args, data) {
+
+        // FIXME: make this API stream
+        egCore.net.request(
+            'open-ils.circ', method, egCore.auth.token(), args
+
+        ).then(function(resp) {
+            if (evt = egCore.evt.parse(resp)) return alert(evt);
+
+            var item = {num_uses : resp.length};
+            item.copy = data.copy;
+            item.title = data.title || 
+                data.copy.call_number().record().simple_record().title();
+            item.index = checkouts.length;
+
+            checkouts.unshift(item);
+            provider.increment();
+        });
+    }
+
+}])