LP#1832897: add miscellaneous carousels functionality to staff interface
authorGalen Charlton <gmc@equinoxinitiative.org>
Fri, 14 Jun 2019 20:42:52 +0000 (16:42 -0400)
committerJane Sandberg <sandbej@linnbenton.edu>
Wed, 4 Sep 2019 02:32:13 +0000 (19:32 -0700)
* Add a 'Create Carousel from Bucket' action in the record bucket interface
* Add an 'Add to Carousel' action to the record details page

Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
Open-ILS/src/templates/staff/cat/bucket/record/t_create_carousel.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/cat/bucket/record/t_grid_menu.tt2
Open-ILS/src/templates/staff/cat/catalog/t_add_to_carousel.tt2 [new file with mode: 0644]
Open-ILS/src/templates/staff/cat/catalog/t_catalog.tt2
Open-ILS/web/js/ui/default/staff/cat/bucket/record/app.js
Open-ILS/web/js/ui/default/staff/cat/catalog/app.js

diff --git a/Open-ILS/src/templates/staff/cat/bucket/record/t_create_carousel.tt2 b/Open-ILS/src/templates/staff/cat/bucket/record/t_create_carousel.tt2
new file mode 100644 (file)
index 0000000..72bb761
--- /dev/null
@@ -0,0 +1,24 @@
+<!-- create carousel dialog -->
+
+<!-- use <form> so we get submit-on-enter for free -->
+<form class="form-validated" novalidate name="form" ng-submit="ok(args)">
+  <div>
+    <div class="modal-header">
+      <button type="button" class="close" 
+        ng-click="cancel()" aria-hidden="true">&times;</button>
+      <h4 class="modal-title">[% l('Create Carousel From Bucket') %]</h4>
+    </div>
+    <div class="modal-body">
+      <div class="form-group">
+        <label for="create-carousel-name">[% l('Name') %]</label>
+        <input type="text" class="form-control" focus-me='focusMe' required
+          id="create-carousel-name" ng-model="args.name" placeholder="[% l('Carousel Name..') %]"/>
+      </div>
+    </div>
+    <div class="modal-footer">
+      <input type="submit" ng-disabled="form.$invalid" 
+          class="btn btn-primary" value="[% l('Create Carousel') %]"/>
+      <button class="btn btn-warning" ng-click="cancel()">[% l('Cancel') %]</button>
+    </div>
+  </div> <!-- modal-content -->
+</form>
index 47704fb..c9af4f5 100644 (file)
@@ -12,6 +12,9 @@
 <eg-grid-menu-item label="[% l('Shared Bucket') %]" 
   handler="openSharedBucketDialog"></eg-grid-menu-item>
 
+<eg-grid-menu-item label="[% l('Create Carousel from Bucket') %]"
+  handler="openCreateCarouselDialog"></eg-grid-menu-item>
+
 <eg-grid-menu-item divider="true"></eg-grid-menu-item>
 
 <eg-grid-menu-item ng-repeat="bkt in bucketSvc.allBuckets" 
diff --git a/Open-ILS/src/templates/staff/cat/catalog/t_add_to_carousel.tt2 b/Open-ILS/src/templates/staff/cat/catalog/t_add_to_carousel.tt2
new file mode 100644 (file)
index 0000000..17aa732
--- /dev/null
@@ -0,0 +1,28 @@
+<div class="modal-header">
+  <button type="button" class="close" ng-click="cancel()"
+    aria-hidden="true">&times;</button>
+  <h4 class="modal-title">[% l('Add to Carousel') %]</h4>
+</div>
+<div class="modal-body">
+  <div class="row">
+    <div class="col-md-4">
+      <label for="select-carousel">[% l('Name of Carousel') %]</label>
+    </div>
+    <div class="col-md-4">
+      <!-- we're taking a short-cut and indexing by the carousel's bucket -->
+      <select id="select-carousel" class="form-control" ng-model="bucket_id"
+              ng-options="carousel.bucket as carousel.name for carousel in allCarousels | orderBy:'name'">
+      </select>
+    </div>
+    <div class="col-md-4">
+      <button class="btn btn-primary" ng-class="{disabled : !bucket_id}" 
+          ng-click="add_to_carousel()">[% l('Add to Selected Carousel') %]</button>
+    </div>
+  </div>
+  </div>
+</div>
+<div class="modal-footer">
+  <div class="col-md-6 pull-right">
+    <button class="btn btn-warning" ng-click="cancel($event)">[% l('Cancel') %]</button>
+  </div>
+</div>
index c9b733d..3f62abb 100644 (file)
                         [% l('Add To Bucket') %]
                     </a>
             </li>
+             <li role="menuitem" ng-class="{disabled : !carousels_available}">
+                    <a ng-click="add_to_carousel()" href="">
+                        [% l('Add To Carousel') %]
+                    </a>
+            </li>
             <li role="menuitem">
                    <a ng-click="view_place_orders()" href="">
                         [% l('View/Place Orders') %]
index 14ebe42..29d64cc 100644 (file)
@@ -401,6 +401,34 @@ function($scope,  $location,  $q,  $timeout,  $uibModal,
         });
     }
 
+    // allows user to create a carousel from the selected bucket
+    $scope.openCreateCarouselDialog = function() {
+        if (!bucketSvc.currentBucket || !bucketSvc.currentBucket.id()) {
+            return;
+        }
+        $uibModal.open({
+            templateUrl: './cat/bucket/record/t_create_carousel',
+            backdrop: 'static',
+            controller :
+                ['$scope', '$uibModalInstance', function($scope, $uibModalInstance) {
+                $scope.focusMe = true;
+                $scope.ok = function(args) {
+                    if (args && args.name) {
+                        return egCore.net.request(
+                            'open-ils.actor',
+                            'open-ils.actor.carousel.create.from_bucket',
+                            egCore.auth.token(), args.name, bucketSvc.currentBucket.id()
+                        ).then(function(carouselId) { $uibModalInstance.close(carouselId) });
+                    }
+                }
+                $scope.cancel = function() { $uibModalInstance.dismiss() }
+            }]
+        }).result.then(function(carouselId) {
+            // bouncing outside of AngularJS
+            $window.location.href = '/eg2/en-US/staff/admin/server/container/carousel';
+        });
+    }
+
     // opens the record export dialog
     $scope.openExportBucketDialog = function() {
         $uibModal.open({
index c853cb8..c207b97 100644 (file)
@@ -423,6 +423,58 @@ function($scope , $routeParams , $location , $window , $q , egCore , egHolds , e
         });
     }
 
+    $scope.carousels_available = false;
+    egCore.net.request(
+        'open-ils.actor',
+        'open-ils.actor.carousel.retrieve_manual_by_staff',
+        egCore.auth.token()
+    ).then(function(carousels) { $scope.carousels_available = true; });
+
+    $scope.add_to_carousel = function(recs) {
+        if (!angular.isArray(recs)) {
+            recs = [ $scope.record_id ];
+        }
+        return $uibModal.open({
+            templateUrl: './cat/catalog/t_add_to_carousel',
+            backdrop: 'static',
+            animation: true,
+            size: 'md',
+            controller:
+                   ['$scope','$uibModalInstance',
+            function($scope , $uibModalInstance) {
+                $scope.bucket_id = 0;
+                $scope.allCarousels = [];
+                egCore.net.request(
+                    'open-ils.actor',
+                    'open-ils.actor.carousel.retrieve_manual_by_staff',
+                    egCore.auth.token()
+                ).then(function(carousels) { $scope.allCarousels = carousels; });
+
+                $scope.add_to_carousel = function() {
+                    // or more precisely, the carousel's bucket
+                    var promises = [];
+                    angular.forEach(recs, function(recId) {
+                        var item = new egCore.idl.cbrebi();
+                        item.bucket($scope.bucket_id);
+                        item.target_biblio_record_entry(recId);
+                        promises.push(egCore.net.request(
+                            'open-ils.actor',
+                            'open-ils.actor.container.item.create',
+                            egCore.auth.token(), 'biblio', item
+                        ));
+                    });
+                    $q.all(promises).then(function(resp) {
+                        $uibModalInstance.close();
+                    });
+                }
+
+                $scope.cancel = function() {
+                    $uibModalInstance.dismiss();
+                }
+            }]
+        });
+    }
+
     $scope.current_overlay_target     = egCore.hatch.getLocalItem('eg.cat.marked_overlay_record');
     $scope.current_transfer_target    = egCore.hatch.getLocalItem('eg.cat.transfer_target_record');
     $scope.current_conjoined_target   = egCore.hatch.getLocalItem('eg.cat.marked_conjoined_record');