[open-ils-commits] [GIT] Evergreen ILS branch rel_3_1 updated. 20ec0244040090a8ac915a28fae9b9acabbecd68

Evergreen Git git at git.evergreen-ils.org
Thu Sep 20 12:36:53 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_1 has been updated
       via  20ec0244040090a8ac915a28fae9b9acabbecd68 (commit)
       via  b464321d69646f31334780dfa6e1f0412df8b3bc (commit)
       via  b5d3db5888e5edf993e9033fa926c05256dfe972 (commit)
      from  e857161a2766d6346e1a4c4f7a75e4c1eb48487b (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 20ec0244040090a8ac915a28fae9b9acabbecd68
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>

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 ef65672..f628abe 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
@@ -151,7 +151,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'},
             {
@@ -1580,17 +1580,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();
             });
 
         });
@@ -1764,45 +1764,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) {
@@ -2487,7 +2487,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 b464321d69646f31334780dfa6e1f0412df8b3bc
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>

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 2b627a1..ef65672 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
@@ -165,6 +165,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)},
@@ -1568,6 +1582,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;
@@ -1809,9 +1834,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 b5d3db5888e5edf993e9033fa926c05256dfe972
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>
    
    Conflicts:
    	Open-ILS/src/templates/staff/cat/volcopy/index.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 9fe2a28..9dcfc6d 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>
 
@@ -149,6 +155,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">
@@ -165,6 +174,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>
 
@@ -185,6 +197,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">
@@ -201,6 +216,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>
 
@@ -223,9 +241,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>
 
@@ -247,9 +271,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>
 
@@ -271,6 +301,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">
@@ -287,6 +320,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>
 
@@ -317,9 +353,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>
 
@@ -341,6 +383,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">
@@ -357,6 +402,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>
 
@@ -375,6 +423,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
@@ -409,6 +460,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 b09efac..2b627a1 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
@@ -1086,6 +1086,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();
@@ -1117,6 +1118,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
     }
 
     $scope.working = {
+        MultiMap: {},
         statcats: {},
         statcats_multi: {},
         statcat_filter: undefined
@@ -1277,6 +1279,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                     });
                 }
             });
+            delete $scope.working.MultiMap[k];
             egCore.hatch.setItem('cat.copy.last_template', n);
         }
 
@@ -1360,6 +1363,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',
@@ -1557,6 +1641,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]()
@@ -1564,10 +1649,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]());
@@ -2358,6 +2446,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 4ee2c23..bbef796 100644
--- a/Open-ILS/web/js/ui/default/staff/services/grid.js
+++ b/Open-ILS/web/js/ui/default/staff/services/grid.js
@@ -274,6 +274,10 @@ angular.module('egGridMod',
                     return grid.getSelectedItems()
                 }
 
+                controls.selectItemsByValue = function(c,v) {
+                    return grid.selectItemsByValue(c,v)
+                }
+
                 controls.allItems = function() {
                     return $scope.items;
                 }
@@ -708,6 +712,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 95a1f48..a2d6b3f 100644
--- a/Open-ILS/web/js/ui/default/staff/services/ui.js
+++ b/Open-ILS/web/js/ui/default/staff/services/ui.js
@@ -1001,6 +1001,50 @@ function($uibModal , $interpolate , egCore) {
     };
 })
 
+.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