[open-ils-commits] [GIT] Evergreen ILS branch rel_3_0 updated. fc105fc32494a73c872c0b2e8a9362e2fc2d9f33

Evergreen Git git at git.evergreen-ils.org
Thu Sep 20 13:49:26 EDT 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, rel_3_0 has been updated
       via  fc105fc32494a73c872c0b2e8a9362e2fc2d9f33 (commit)
       via  918533b7cff1e7f123e1025d52ccdc1a87e40063 (commit)
       via  9a7b44e12bbd20d1639d146c669c9282bad49875 (commit)
      from  76fa907a2fd76bbfb3899f302109f9d51c6d756e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit fc105fc32494a73c872c0b2e8a9362e2fc2d9f33
Author: Mike Rylander <mrylander at gmail.com>
Date:   Fri Aug 3 17:25:33 2018 -0400

    LP#1732761: Chain the promises to avoid races
    
    It looks like there's a race condition gathering locations for larger copy
    sets.  Here we chain the promises to remove the race by serialization.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>
    Signed-off-by: Jason Stephenson <jason at sigio.com>
    
    Conflicts:
    	Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js

diff --git a/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js b/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
index 2b5f236..2544c17 100644
--- a/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
+++ b/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
@@ -136,7 +136,7 @@ function(egCore , $q) {
         );
     };
 
-    service.get_locations = function(orgs) {
+    service.get_locations_by_org = function(orgs) {
         return egCore.pcrud.search('acpl',
             {owning_lib : orgs, deleted : 'f'},
             {
@@ -1505,17 +1505,17 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
             }
 
         }).then( function() {
-            $scope.data = itemSvc;
-            $scope.workingGridDataProvider.refresh();
 
             return itemSvc.fetch_locations(
-                $scope.data.copies.map(function(cp){
+                itemSvc.copies.map(function(cp){
                     return cp.location();
                 }).filter(function(e,i,a){
                     return a.lastIndexOf(e) === i;
                 })
             ).then(function(list){
+                $scope.data = itemSvc;
                 $scope.location_list = list;
+                $scope.workingGridDataProvider.refresh();
             });
 
         });
@@ -1689,45 +1689,45 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                 if ($scope.location_orgs.toString() != final_orgs.toString()) {
                     $scope.location_orgs = final_orgs;
                     if ($scope.location_orgs.length) {
-                        itemSvc.get_locations($scope.location_orgs).then(function(list){
+                        itemSvc.get_locations_by_org($scope.location_orgs).then(function(list){
                             angular.forEach(list, function(l) {
                                 $scope.location_cache[ ''+l.id() ] = l;
                             });
                             $scope.location_list = list;
-                        });
-
-                        $scope.statcat_filter_list = [];
-                        angular.forEach($scope.location_orgs, function (o) {
-                            $scope.statcat_filter_list.push(egCore.org.get(o));
-                        });
+                        }).then(function() {
+                            $scope.statcat_filter_list = [];
+                            angular.forEach($scope.location_orgs, function (o) {
+                                $scope.statcat_filter_list.push(egCore.org.get(o));
+                            });
 
-                        itemSvc.get_statcats($scope.location_orgs).then(function(list){
-                            $scope.statcats = list;
-                            angular.forEach($scope.statcats, function (s) {
+                            itemSvc.get_statcats($scope.location_orgs).then(function(list){
+                                $scope.statcats = list;
+                                angular.forEach($scope.statcats, function (s) {
 
-                                if (!$scope.working)
-                                    $scope.working = { statcats_multi: {}, statcats: {}, statcat_filter: undefined};
-                                if (!$scope.working.statcats_multi)
-                                    $scope.working.statcats_multi = {};
-                                if (!$scope.working.statcats)
-                                    $scope.working.statcats = {};
+                                    if (!$scope.working)
+                                        $scope.working = { statcats_multi: {}, statcats: {}, statcat_filter: undefined};
+                                    if (!$scope.working.statcats_multi)
+                                        $scope.working.statcats_multi = {};
+                                    if (!$scope.working.statcats)
+                                        $scope.working.statcats = {};
 
-                                if (!$scope.in_item_select) {
-                                    $scope.working.statcats[s.id()] = undefined;
-                                }
-                                createStatcatUpdateWatcher(s.id());
+                                    if (!$scope.in_item_select) {
+                                        $scope.working.statcats[s.id()] = undefined;
+                                    }
+                                    createStatcatUpdateWatcher(s.id());
+                                });
+                                $scope.in_item_select = false;
+                                // do a refresh here to work around a race
+                                // condition that can result in stat cats
+                                // not being selected.
+                                $scope.workingGridDataProvider.refresh();
                             });
-                            $scope.in_item_select = false;
-                            // do a refresh here to work around a race
-                            // condition that can result in stat cats
-                            // not being selected.
-                            $scope.workingGridDataProvider.refresh();
                         });
                     }
                 }
+            } else {
+                $scope.workingGridDataProvider.refresh();
             }
-
-            $scope.workingGridDataProvider.refresh();
         });
 
         $scope.statcat_visible = function (sc_owner) {
@@ -2339,7 +2339,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                 $scope.location_cache = {};
             
                 $scope.location_list = [];
-                itemSvc.get_locations(
+                itemSvc.get_locations_by_org(
                     egCore.org.fullPath( egCore.auth.user().ws_ou(), true )
                 ).then(function(list){
                     $scope.location_list = list;

commit 918533b7cff1e7f123e1025d52ccdc1a87e40063
Author: Mike Rylander <mrylander at gmail.com>
Date:   Mon Jul 9 16:31:50 2018 -0400

    LP#1732761: Fetch locations immediately for display
    
    This commit closes a race condition where location labels cannot be rendered
    for the "multiple locations" widget because fetching them takes longer than
    the initial render of the attribute editor.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>
    Signed-off-by: Jason Stephenson <jason at sigio.com>

diff --git a/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js b/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
index 3187d45..2b5f236 100644
--- a/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
+++ b/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
@@ -150,6 +150,20 @@ function(egCore , $q) {
         );
     };
 
+    service.fetch_locations = function(locs) {
+        return egCore.pcrud.search('acpl',
+            {id : locs},
+            {
+                flesh : 1,
+                flesh_fields : {
+                    acpl : ['owning_lib']
+                },
+                order_by : { acpl : 'name' }
+            },
+            {atomic : true}
+        );
+    };
+
     service.get_suffixes = function(org) {
         return egCore.pcrud.search('acns',
             {owning_lib : egCore.org.fullPath(org, true)},
@@ -1493,6 +1507,17 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
         }).then( function() {
             $scope.data = itemSvc;
             $scope.workingGridDataProvider.refresh();
+
+            return itemSvc.fetch_locations(
+                $scope.data.copies.map(function(cp){
+                    return cp.location();
+                }).filter(function(e,i,a){
+                    return a.lastIndexOf(e) === i;
+                })
+            ).then(function(list){
+                $scope.location_list = list;
+            });
+
         });
 
         $scope.can_save = false;
@@ -1734,9 +1759,6 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
         });
 
         $scope.location_list = [];
-        itemSvc.get_locations().then(function(list){
-            $scope.location_list = list;
-        });
         createSimpleUpdateWatcher('location');
 
         $scope.status_list = [];

commit 9a7b44e12bbd20d1639d146c669c9282bad49875
Author: Mike Rylander <mrylander at gmail.com>
Date:   Tue Jul 3 16:57:27 2018 -0400

    LP#1732761: Batch item edit and multiple values per field
    
    Previous to this commit, the display of multiple different values for a field
    in the item attribute editor was simply to display no value.  Here we add a UI
    component that presents the list of unique values, the number of selected
    copies that use each value, and the ability to select just those copies using
    a particular value by clicking on the desired value.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Kathy Lussier <klussier at masslnc.org>
    Signed-off-by: Jason Stephenson <jason at sigio.com>
    
    Conflicts:
    	Open-ILS/src/templates/staff/cat/volcopy/index.tt2
    	Open-ILS/src/templates/staff/cat/volcopy/t_attr_edit.tt2

diff --git a/Open-ILS/src/templates/staff/cat/volcopy/index.tt2 b/Open-ILS/src/templates/staff/cat/volcopy/index.tt2
index f93cb56..318db6a 100644
--- a/Open-ILS/src/templates/staff/cat/volcopy/index.tt2
+++ b/Open-ILS/src/templates/staff/cat/volcopy/index.tt2
@@ -15,6 +15,14 @@
 angular.module('egCoreMod').run(['egStrings', function(s) {
     s.VOL_COPY_TEMPLATE_SUCCESS_SAVE = "[% l('Saved volume/copy template(s)') %]";
     s.VOL_COPY_TEMPLATE_SUCCESS_DELETE = "[% l('Deleted volume/copy template') %]";
+    s.SHORT = "[% l('Short') %]";
+    s.LOW = "[% l('Low') %]";
+    s.NORMAL = "[% l('Normal') %]";
+    s.EXTENDED = "[% l('Extended') %]";
+    s.HIGH = "[% l('High') %]";
+    s.UNSET = "[% l('UNSET') %]";
+    s.YES = "[% l('Yes') %]";
+    s.NO = "[% l('No') %]";
     [%# Note the "~" characters escape the gettext brackets %]
     s.COPY_NOTE_INITIALS = 
       "[% l('[_1] ~[ [_2] @ [_3] ~]', '{{value}}', '{{initials}}', '{{ws_ou}}') %]"
diff --git a/Open-ILS/src/templates/staff/cat/volcopy/t_attr_edit.tt2 b/Open-ILS/src/templates/staff/cat/volcopy/t_attr_edit.tt2
index d63b37b..15462de 100644
--- a/Open-ILS/src/templates/staff/cat/volcopy/t_attr_edit.tt2
+++ b/Open-ILS/src/templates/staff/cat/volcopy/t_attr_edit.tt2
@@ -120,12 +120,18 @@
                             </label>
                         </div>
                     </div>
+                    <div class="container" ng-show="working.MultiMap.circulate.length > 1 && working.circulate === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.circulate" render="labelYesNo" on-select="select_by_circulate"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6" ng-class="{'bg-success': working.status !== undefined}">
                     <select class="form-control"
                         ng-disabled="!defaults.attributes.status" ng-model="working.status"
                         ng-options="s.id() as s.name() disable when magic_status_list.indexOf(s.id(),0) > -1 for s in status_list">
                     </select>
+                    <div class="container" ng-show="working.MultiMap.status.length > 1 && working.status === undefined">
+                        <eg-list-counts label="[% l('Multiple statuses') %]" list="working.MultiMap.status" render="statusName" on-select="select_by_status"></eg-list-counts>
+                    </div>
                 </div>
             </div>
 
@@ -150,6 +156,9 @@
                         label="[% l('(Unset)') %]"
                         disable-test="cant_have_vols"
                     ></eg-org-selector>
+                    <div class="container" ng-show="working.MultiMap.circ_lib.length > 1 && working.circ_lib === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.circ_lib" render="orgShortname" on-select="select_by_circ_lib"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6" ng-class="{'bg-success': working.ref !== undefined}">
                     <div class="row">
@@ -166,6 +175,9 @@
                             </label>
                         </div>
                     </div>
+                    <div class="container" ng-show="working.MultiMap.ref.length > 1 && working.ref === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.ref" render="labelYesNo" on-select="select_by_ref"></eg-list-counts>
+                    </div>
                 </div>
             </div>
 
@@ -186,6 +198,9 @@
                         ng-disabled="!defaults.attributes.location" ng-model="working.location"
                         ng-options="l.id() as i18n.ou_qualified_location_name(l) for l in location_list"
                     ></select>
+                    <div class="container" ng-show="working.MultiMap.location.length > 1 && working.location === undefined">
+                        <eg-list-counts label="[% l('Multiple locations') %]" list="working.MultiMap.location" render="locationName" on-select="select_by_location"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6" ng-class="{'bg-success': working.opac_visible !== undefined}">
                     <div class="row">
@@ -202,6 +217,9 @@
                             </label>
                         </div>
                     </div>
+                    <div class="container" ng-show="working.MultiMap.opac_visible.length > 1 && working.opac_visible === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.opac_visible" render="labelYesNo" on-select="select_by_opac_visible"></eg-list-counts>
+                    </div>
                 </div>
             </div>
 
@@ -224,9 +242,15 @@
                     >
                         <option value="">[% l('<NONE>') %]</option>
                     </select>
+                    <div class="container" ng-show="working.MultiMap.circ_modifier.length > 1 && working.circ_modifier === undefined">
+                        <eg-list-counts label="[% l('Multiple modifiers') %]" list="working.MultiMap.circ_modifier" render="circmodName" on-select="select_by_circ_modifier"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6" ng-class="{'bg-success': working.price !== undefined}">
                     <input class="form-control" ng-disabled="!defaults.attributes.price" str-to-float ng-model="working.price" type="number" step="0.01"/>
+                    <div class="container" ng-show="working.MultiMap.price.length > 1 && working.price === undefined">
+                        <eg-list-counts label="[% l('Multiple prices') %]" list="working.MultiMap.price" on-select="select_by_price"></eg-list-counts>
+                    </div>
                 </div>
             </div>
 
@@ -248,9 +272,15 @@
                         <option value="2" selected>[% l('Normal') %]</option>
                         <option value="3">[% l('Extended') %]</option>
                     </select>
+                    <div class="container" ng-show="working.MultiMap.loan_duration.length > 1 && working.loan_duration === undefined">
+                        <eg-list-counts label="[% l('Multiple durations') %]" list="working.MultiMap.loan_duration" render="durationLabel" on-select="select_by_loan_duration"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6" ng-class="{'bg-success': working.cost !== undefined}">
                     <input class="form-control" ng-disabled="!defaults.attributes.cost" str-to-float ng-model="working.cost" type="number" step="0.01"/>
+                    <div class="container" ng-show="working.MultiMap.cost.length > 1 && working.cost === undefined">
+                        <eg-list-counts label="[% l('Multiple costs') %]" list="working.MultiMap.cost" on-select="select_by_cost"></eg-list-counts>
+                    </div>
                 </div>
             </div>
 
@@ -272,6 +302,9 @@
                         ng-options="t.code() as t.value() for t in circ_type_list">
                       <option value="">[% l('<NONE>') %]</option>
                     </select>
+                    <div class="container" ng-show="working.MultiMap.circ_as_type.length > 1 && working.circ_as_type === undefined">
+                        <eg-list-counts label="[% l('Multiple types') %]" list="working.MultiMap.circ_as_type" render="circTypeValue" on-select="select_by_circ_as_type"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6" ng-class="{'bg-success': working.deposit !== undefined}">
                     <div class="row">
@@ -288,6 +321,9 @@
                             </label>
                         </div>
                     </div>
+                    <div class="container" ng-show="working.MultiMap.deposit.length > 1 && working.deposit === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.deposit" render="labelYesNo" on-select="select_by_deposit"></eg-list-counts>
+                    </div>
                 </div>
             </div>
 
@@ -318,9 +354,15 @@
                             </label>
                         </div>
                     </div>
+                    <div class="container" ng-show="working.MultiMap.holdable.length > 1 && working.holdable === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.holdable" render="labelYesNo" on-select="select_by_holdable"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6" ng-class="{'bg-success': working.deposit_amount !== undefined}">
                     <input class="form-control" ng-disabled="!defaults.attributes.deposit_amount" str-to-float ng-model="working.deposit_amount" type="number" step="0.01"/>
+                    <div class="container" ng-show="working.MultiMap.deposit_amount.length > 1 && working.deposit_amount === undefined">
+                        <eg-list-counts label="[% l('Multiple amounts') %]" list="working.MultiMap.deposit_amount" on-select="select_by_deposit_amount"></eg-list-counts>
+                    </div>
                 </div>
             </div>
 
@@ -342,6 +384,9 @@
                         ng-options="a.id() as a.name() for a in age_protect_list">
                       <option value="">[% l('<NONE>') %]</option>
                     </select>
+                    <div class="container" ng-show="working.MultiMap.age_protect.length > 1 && working.age_protect === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.age_protect" render="ageprotectName" on-select="select_by_age_protect"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6" ng-class="{'bg-success': working.mint_condition !== undefined}">
                     <div class="row">
@@ -358,6 +403,9 @@
                             </label>
                         </div>
                     </div>
+                    <div class="container" ng-show="working.MultiMap.mint_condition.length > 1 && working.mint_condition === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.mint_condition" render="labelYesNo" on-select="select_by_mint_condition"></eg-list-counts>
+                    </div>
                 </div>
             </div>
 
@@ -376,6 +424,9 @@
                         <option value="2" selected>[% l('Normal') %]</option>
                         <option value="3">[% l('High') %]</option>
                     </select>
+                    <div class="container" ng-show="working.MultiMap.fine_level.length > 1 && working.fine_level === undefined">
+                        <eg-list-counts label="[% l('Multiple levels') %]" list="working.MultiMap.fine_level" render="fineLabel" on-select="select_by_fine_level"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6">
                     <button
@@ -403,6 +454,9 @@
                         ng-options="a.id() as a.name() for a in floating_list">
                       <option value="">[% l('<NONE>') %]</option>
                     </select>
+                    <div class="container" ng-show="working.MultiMap.floating.length > 1 && working.floating === undefined">
+                        <eg-list-counts label="[% l('Multiple values') %]" list="working.MultiMap.floating" render="floatingName" on-select="select_by_floating"></eg-list-counts>
+                    </div>
                 </div>
                 <div class="col-md-6">
                     <button
diff --git a/Open-ILS/src/templates/staff/share/t_listcounts.tt2 b/Open-ILS/src/templates/staff/share/t_listcounts.tt2
new file mode 100644
index 0000000..e32d061
--- /dev/null
+++ b/Open-ILS/src/templates/staff/share/t_listcounts.tt2
@@ -0,0 +1,11 @@
+<div class="btn-group" uib-dropdown>
+    <button type="button" class="btn btn-default" uib-dropdown-toggle>
+        {{label}}
+        <span class="caret"></span>
+    </button>
+    <ul uib-dropdown-menu class="uib-dropdown-menu">
+        <li ng-repeat="item in count_hash">
+            <a href ng-click="selectValue(item.original)">{{item.value}} ({{item.count}})</a>
+        </li>
+    </ul>
+</div>
diff --git a/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js b/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
index 6e1ed33..3187d45 100644
--- a/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
+++ b/Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js
@@ -1067,6 +1067,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
             var newval = $scope.working[field];
 
             if (typeof newval != 'undefined') {
+                delete $scope.working.MultiMap[field];
                 if (angular.isObject(newval)) { // we'll use the pkey
                     if (newval.id) newval = newval.id();
                     else if (newval.code) newval = newval.code();
@@ -1098,6 +1099,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
     }
 
     $scope.working = {
+        MultiMap: {},
         statcats: {},
         statcats_multi: {},
         statcat_filter: undefined
@@ -1202,6 +1204,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                     });
                 }
             });
+            delete $scope.working.MultiMap[k];
             egCore.hatch.setItem('cat.copy.last_template', n);
         }
 
@@ -1285,6 +1288,87 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
         $scope.add_vols_copies = false;
         $scope.is_fast_add = false;
 
+        // Generate some functions for selecting items by column value in the working grid
+        angular.forEach(
+            ['circulate','status','circ_lib','ref','location','opac_visible','circ_modifier','price',
+             'loan_duration','cost','circ_as_type','deposit','holdable','deposit_amount','age_protect',
+             'mint_condition','fine_level','floating'],
+            function (field) {
+                $scope['select_by_' + field] = function (x) {
+                    $scope.workingGridControls.selectItemsByValue(field,x);
+                }
+            }
+        );
+
+        var truthy = /^t|1/;
+        $scope.labelYesNo = function (x) {
+            return truthy.test(x) ? egCore.strings.YES : egCore.strings.NO;
+        }
+
+        $scope.orgShortname = function (x) {
+            return egCore.org.get(x).shortname();
+        }
+
+        $scope.statusName = function (x) {
+            var s = $scope.status_list.filter(function(y) {
+                return y.id() == x;
+            });
+
+            return s[0].name();
+        }
+
+        $scope.locationName = function (x) {
+            var s = $scope.location_list.filter(function(y) {
+                return y.id() == x;
+            });
+
+            return $scope.i18n.ou_qualified_location_name(s[0]);
+        }
+
+        $scope.durationLabel = function (x) {
+            return [egCore.strings.SHORT, egCore.strings.NORMAL, egCore.strings.EXTENDED][-1 + x]
+        }
+
+        $scope.fineLabel = function (x) {
+            return [egCore.strings.LOW, egCore.strings.NORMAL, egCore.strings.HIGH][-1 + x]
+        }
+
+        $scope.circTypeValue = function (x) {
+            if (x === null) return egCore.strings.UNSET;
+            var s = $scope.circ_type_list.filter(function(y) {
+                return y.code() == x;
+            });
+
+            return s[0].value();
+        }
+
+        $scope.ageprotectName = function (x) {
+            if (x === null) return egCore.strings.UNSET;
+            var s = $scope.age_protect_list.filter(function(y) {
+                return y.id() == x;
+            });
+
+            return s[0].name();
+        }
+
+        $scope.floatingName = function (x) {
+            if (x === null) return egCore.strings.UNSET;
+            var s = $scope.floating_list.filter(function(y) {
+                return y.id() == x;
+            });
+
+            return s[0].name();
+        }
+
+        $scope.circmodName = function (x) {
+            if (x === null) return egCore.strings.UNSET;
+            var s = $scope.circ_modifier_list.filter(function(y) {
+                return y.code() == x;
+            });
+
+            return s[0].name();
+        }
+
         egNet.request(
             'open-ils.actor',
             'open-ils.actor.anon_cache.get_value',
@@ -1482,6 +1566,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                 angular.forEach(Object.keys($scope.defaults.attributes), function (attr) {
 
                     var value_hash = {};
+                    var value_list = [];
                     angular.forEach(item_list, function (item) {
                         if (item[attr]) {
                             var v = item[attr]()
@@ -1489,10 +1574,13 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                                 if (v.id) v = v.id();
                                 else if (v.code) v = v.code();
                             }
+                            value_list.push(v);
                             value_hash[v] = 1;
                         }
                     });
 
+                    $scope.working.MultiMap[attr] = value_list;
+
                     if (Object.keys(value_hash).length == 1) {
                         if (attr == 'circ_lib') {
                             $scope.working[attr] = egCore.org.get(item_list[0][attr]());
@@ -2210,6 +2298,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
 
                 $scope.clearWorking = function () {
                     angular.forEach($scope.working, function (v,k,o) {
+                        $scope.working.MultiMap[k] = [];
                         if (!angular.isObject(v)) {
                             if (typeof v != 'undefined')
                                 $scope.working[k] = undefined;
diff --git a/Open-ILS/web/js/ui/default/staff/services/grid.js b/Open-ILS/web/js/ui/default/staff/services/grid.js
index 72d40e5..ce494da 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -266,6 +266,10 @@ angular.module('egGridMod',
                     return grid.getSelectedItems()
                 }
 
+                controls.selectItemsByValue = function(c,v) {
+                    return grid.selectItemsByValue(c,v)
+                }
+
                 controls.allItems = function() {
                     return $scope.items;
                 }
@@ -700,6 +704,21 @@ angular.module('egGridMod',
                 $scope.selected[index] = true;
             }
 
+            // selects items by a column value, first clearing selected list.
+            // we overwrite the object so that we can watch $scope.selected
+            grid.selectItemsByValue = function(column, value) {
+                $scope.selected = {};
+                angular.forEach($scope.items, function(item) {
+                    var col_value;
+                    if (angular.isFunction(item[column]))
+                        col_value = item[column]();
+                    else
+                        col_value = item[column];
+
+                    if (value == col_value) $scope.selected[grid.indexValue(item)] = true
+                }); 
+            }
+
             // selects or deselects an item, without affecting the others.
             // returns true if the item is selected; false if de-selected.
             // we overwrite the object so that we can watch $scope.selected
diff --git a/Open-ILS/web/js/ui/default/staff/services/ui.js b/Open-ILS/web/js/ui/default/staff/services/ui.js
index cd97390..4a6d369 100644
--- a/Open-ILS/web/js/ui/default/staff/services/ui.js
+++ b/Open-ILS/web/js/ui/default/staff/services/ui.js
@@ -736,6 +736,50 @@ function($window , egStrings) {
     };
 })
 
+.directive('egListCounts', function() {
+    return {
+        restrict: 'E',
+        replace: true,
+        scope: {
+            label: "@",
+            list: "=", // list of things
+            render: "=", // function to turn thing into string; default to stringification
+            onSelect: "=" // function to fire when option selected. passed one copy of the selected value
+        },
+        templateUrl: './share/t_listcounts',
+        controller: ['$scope','$timeout',
+            function( $scope , $timeout ) {
+
+                $scope.isopen = false;
+                $scope.count_hash = {};
+
+                $scope.renderer = $scope.render ? $scope.render : function (x) { return ""+x };
+
+                $scope.$watchCollection('list',function() {
+                    $scope.count_hash = {};
+                    angular.forEach($scope.list, function (item) {
+                        var str = $scope.renderer(item);
+                        if (!$scope.count_hash[str]) {
+                            $scope.count_hash[str] = {
+                                count : 1,
+                                value : str,
+                                original : item
+                            };
+                        } else {
+                            $scope.count_hash[str].count++;
+                        }
+                    });
+                });
+
+                $scope.selectValue = function (item) {
+                    if ($scope.onSelect) $scope.onSelect(item);
+                }
+
+            }
+        ]
+    };
+})
+
 /**
  * Nested org unit selector modeled as a Bootstrap dropdown button.
  */

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/src/templates/staff/cat/volcopy/index.tt2 |    8 +
 .../templates/staff/cat/volcopy/t_attr_edit.tt2    |   54 ++++++
 .../src/templates/staff/share/t_listcounts.tt2     |   11 ++
 .../web/js/ui/default/staff/cat/volcopy/app.js     |  179 ++++++++++++++++----
 Open-ILS/web/js/ui/default/staff/services/grid.js  |   19 ++
 Open-ILS/web/js/ui/default/staff/services/ui.js    |   44 +++++
 6 files changed, 281 insertions(+), 34 deletions(-)
 create mode 100644 Open-ILS/src/templates/staff/share/t_listcounts.tt2


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list