webstaff: add MFHD tab to serials management page
authorGalen Charlton <gmc@equinoxinitiative.org>
Tue, 23 May 2017 22:00:12 +0000 (18:00 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Tue, 30 May 2017 16:06:49 +0000 (12:06 -0400)
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/templates/staff/serials/index.tt2
Open-ILS/src/templates/staff/serials/t_manage.tt2
Open-ILS/src/templates/staff/serials/t_mfhd_manager.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/share/t_edit_mfhd.tt2 [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/serials/app.js
Open-ILS/web/js/ui/default/staff/serials/directives/mfhd_manager.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/serials/services/core.js

index 36b7ddc..2944abe 100644 (file)
@@ -6,10 +6,16 @@
 
 [% 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/mfhd.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/serials/services/core.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/serials/app.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/marcrecord.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/cat/services/tagtable.js"></script>
+[% INCLUDE 'staff/cat/share/marcedit_strings.tt2' %]
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/cat/services/marcedit.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/serials/directives/subscription_manager.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/serials/directives/sub_selector.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/serials/directives/mfhd_manager.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/serials/directives/prediction_manager.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/serials/directives/prediction_wizard.js"></script>
 <script src="[% ctx.media_prefix %]/js/ui/default/staff/serials/directives/item_manager.js"></script>
@@ -61,6 +67,8 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
     s.SERIALS_ITEM_STATUS['Not Held'] = "[% l('Not Held' ) %]";
     s.SERIALS_ITEM_STATUS['Not Published'] = "[% l('Not Published') %]";
 
+    s.CONFIRM_DELETE_MFHDS = "[% l('Delete selected MFHD(s)?') %]";
+    s.CONFIRM_DELETE_MFHDS_MESSAGE = "[% l('Will delete {{items}} MFHD(s).') %]";
 }]);
 </script>
 [% END %]
index 232fbfb..6751f02 100644 (file)
             bib-id="bib_id" ssub-id="ssub.id">
         </eg-item-manager>
       </uib-tab>
+      <uib-tab index="'manage-mfhds'" heading="[% l('Manage MFHDs') %]">
+        <eg-mfhd-manager ng-if="active_tab == 'manage-mfhds'"
+            bib-id="bib_id">
+        </eg-mfhd-manager>
+      </uib-tab>
     </uib-tabset>
   </div>
 </div>
diff --git a/Open-ILS/src/templates/staff/serials/t_mfhd_manager.tt2 b/Open-ILS/src/templates/staff/serials/t_mfhd_manager.tt2
new file mode 100644 (file)
index 0000000..6568fee
--- /dev/null
@@ -0,0 +1,26 @@
+<div>
+  <eg-grid
+    id-field="id"
+    features="-display,-sort,-multisort"
+    items-provider="mfhdGridDataProvider"
+    grid-controls="mfhdGridControls"
+    persist-key="serials.mfhd_grid">
+
+    <eg-grid-menu-item handler="createMfhd"
+      label="[% l('Create MFHD') %]"
+    />
+
+    <eg-grid-action handler="edit_mfhd" disabled="need_one_selected"
+      label="[% l('Edit MFHD') %]"></eg-grid-action>
+    <eg-grid-action handler="delete_mfhds"
+      label="[% l('Delete Selected MFHDs') %]"></eg-grid-action>
+
+    <eg-grid-field label="[% l('ID') %]"             path="id"              visible></eg-grid-field>
+    <eg-grid-field label="[% l('Owning Library') %]" path="owning_lib.name" visible></eg-grid-field>
+    <eg-grid-field label="[% l('Basic Holdings') %]" path="basic_holdings" visible></eg-grid-field>
+    <eg-grid-field label="[% l('Index Holdings') %]" path="index_holdings" hidden></eg-grid-field>
+    <eg-grid-field label="[% l('Supplement Holdings') %]" path="supplement_holdings" hidden></eg-grid-field>
+
+  </eg-grid>
+</div>
diff --git a/Open-ILS/src/templates/staff/share/t_edit_mfhd.tt2 b/Open-ILS/src/templates/staff/share/t_edit_mfhd.tt2
new file mode 100644 (file)
index 0000000..807207f
--- /dev/null
@@ -0,0 +1,16 @@
+<div>
+  <div class="modal-header">
+    <button type="button" class="close"
+      ng-click="cancel()" aria-hidden="true">&times;</button>
+    <h4 class="modal-title">[% l('Edit MARC Holdings Record') %]</h4>
+  </div>
+  <div class="modal-body">
+    <eg-marc-edit-record dirty-flag="dirty_flag" marc-xml="args.marc_xml"
+                         in-place-mode="true" record-type="sre" save-label="[% l('Modify') %]" />
+  </div>
+  <div class="modal-footer">
+    <input type="submit" ng-click="ok(args)"
+        class="btn btn-primary" value="[% l('Use Edits') %]"/>
+    <button class="btn btn-warning" ng-click="cancel()">[% l('Cancel') %]</button>
+  </div>
+</div>
index e5eeb5a..31f925e 100644 (file)
@@ -1,4 +1,4 @@
-angular.module('egSerialsApp', ['ui.bootstrap','ngRoute','egCoreMod','egGridMod','ngToast','egSerialsMod','egSerialsAppDep']);
+angular.module('egSerialsApp', ['ui.bootstrap','ngRoute','egCoreMod','egGridMod','ngToast','egSerialsMod','egMfhdMod','egMarcMod','egSerialsAppDep']);
 angular.module('egSerialsAppDep', []);
 
 angular.module('egSerialsApp')
diff --git a/Open-ILS/web/js/ui/default/staff/serials/directives/mfhd_manager.js b/Open-ILS/web/js/ui/default/staff/serials/directives/mfhd_manager.js
new file mode 100644 (file)
index 0000000..06d6e95
--- /dev/null
@@ -0,0 +1,97 @@
+angular.module('egSerialsAppDep')
+
+.directive('egMfhdManager', function() {
+    return {
+        transclude: true,
+        restrict:   'E',
+        scope: {
+            bibId  : '=',
+        },
+        templateUrl: './serials/t_mfhd_manager',
+        controller:
+       ['$scope','$q','egSerialsCoreSvc','egCore','egGridDataProvider',
+        '$uibModal','$timeout','egMfhdCreateDialog','egConfirmDialog',
+function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider ,
+         $uibModal , $timeout , egMfhdCreateDialog , egConfirmDialog) {
+
+    function reload() {
+        egSerialsCoreSvc.fetch_mfhds($scope.bibId).then(function() {
+            $scope.mfhdGridDataProvider.refresh();
+        });
+    }
+    reload();
+
+    $scope.mfhdGridControls = {
+        activateItem : function (item) { } // TODO
+    };
+    $scope.mfhdGridDataProvider = egGridDataProvider.instance({
+        get : function(offset, count) {
+            return this.arrayNotifier(egSerialsCoreSvc.flatMfhdList, offset, count);
+        }
+    });
+    $scope.need_one_selected = function() {
+        var items = $scope.mfhdGridControls.selectedItems();
+        if (items.length == 1) return false;
+        return true;
+    };
+
+    $scope.createMfhd = function() {
+        egMfhdCreateDialog.open($scope.bibId).result.then(function() {
+            reload();
+        });
+    };
+
+    $scope.edit_mfhd = function() {
+        var items = $scope.mfhdGridControls.selectedItems();
+        if (items.length != 1) return;
+        var args = {
+            'marc_xml' : items[0].marc_xml
+        }
+        $uibModal.open({
+            templateUrl: './share/t_edit_mfhd',
+            size: 'lg',
+            controller:
+                ['$scope', '$uibModalInstance', function($scope, $uibModalInstance) {
+                $scope.focusMe = true;
+                $scope.args = args;
+                $scope.dirty_flag = false;
+                $scope.ok = function(args) { $uibModalInstance.close(args) }
+                $scope.cancel = function () { $uibModalInstance.dismiss() }
+            }]
+        }).result.then(function (args) {
+            egCore.pcrud.retrieve('sre', items[0].id).then(function(sre) {
+                sre.marc(args.marc_xml);
+                egCore.pcrud.update(sre).then(function() {
+                    reload();
+                });
+            });
+        });
+    };
+
+    $scope.delete_mfhds = function() {
+        var items = $scope.mfhdGridControls.selectedItems();
+        if (items.length <= 0) return;
+        
+        egConfirmDialog.open(
+            egCore.strings.CONFIRM_DELETE_MFHDS,
+            egCore.strings.CONFIRM_DELETE_MFHDS_MESSAGE,
+            {items : items.length}
+        ).result.then(function () {
+            var promises = [];
+            angular.forEach(items, function(mfhd) {
+                var promise = $q.defer();
+                promises.push(promise.promise);    
+                egCore.pcrud.retrieve('sre', mfhd.id).then(function(sre) {
+                    egCore.pcrud.remove(sre).then(function() {
+                        promise.resolve();
+                    });
+                })
+            });
+            $q.all(promises).then(function() {
+                reload();
+            });
+        });
+    }
+}]
+    }
+})
index edf250e..db707a5 100644 (file)
@@ -9,6 +9,8 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
         subTree : [],
         subList : [],
         sptList : [],
+        mfhdList : [],
+        flatMfhdList : [],
         itemMap : {},
         itemTree : [],
         itemList : [],
@@ -99,6 +101,26 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
         }
     }
 
+    service.fetch_mfhds = function(bibId, contextOrg) {
+        // TODO filter by contextOrg
+        return egCore.pcrud.search('sre', {
+                record       : bibId,
+                deleted      : 'f',
+                active       : 't'
+            }, {
+                flesh : 3,
+                flesh_fields : {
+                    'sre' : ['owning_lib']
+                }
+            },
+            { atomic : true }
+        ).then(function(list) {
+            service.bibId = bibId;
+            service.mfhdList = list;
+            update_flat_mfhd_list();
+        });
+    }
+
     // fetch subscription, distributions, streams, captions,
     // and notes associated with the indicated bib
     service.fetch = function(bibId, contextOrg) {
@@ -428,6 +450,38 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
         });
     }
 
+    function update_flat_mfhd_list() {
+        var list = [];
+        angular.forEach(service.mfhdList, function(sre) {
+            var mfhdHash = egCore.idl.toHash(sre);
+            var rec = new MARC21.Record({ marcxml : mfhdHash.marc });
+            var _mfhd = {
+                'id'                   : mfhdHash.id,
+                'owning_lib.name'      : mfhdHash.owning_lib.name,
+                'owning_lib.id'        : mfhdHash.owning_lib.id,
+                'marc'                 : rec.toBreaker(),
+                'marc_xml'             : mfhdHash.marc,
+                'svr'                  : null,
+                'basic_holdings'       : null,
+                'index_holdings'       : null,
+                'supplement_holdings'  : null
+            }
+            list.push(_mfhd);
+            egCore.net.request(
+                'open-ils.search',
+                'open-ils.search.serial.record.mfhd.retrieve',
+                mfhdHash.id
+            ).then(function(svr) {
+                _mfhd.svr = egCore.idl.toTypedHash(svr);
+                _mfhd.basic_holdings = _mfhd.svr.basic_holdings.join("; ");
+                _mfhd.index_holdings = _mfhd.svr.index_holdings.join("; ");
+                _mfhd.supplement_holdings = _mfhd.svr.supplement_holdings.join("; ");
+            })
+        });
+        service.flatMfhdList.length = 0;
+        angular.extend(service.flatMfhdList, list);
+    }
+
     // create/update a flat version of the subscription/distribution/stream
     // tree for feeding to the distribution and stream grid
     function update_flat_sdist_sstr_list() {