From: Galen Charlton Date: Mon, 24 Apr 2017 21:05:19 +0000 (-0400) Subject: webstaff: reorganize serials app layout X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=783350c11d50835a6bc3627dcee51769085d5182;p=working%2FEvergreen.git webstaff: reorganize serials app layout This patch lays the groundwork for breaking out each tab in the main page into a separate directive, and establishes the directive for the subscription manager. Note that at present stuff under serials/directives is expected to be firmly bound with other aspects of the over serials app, including its services. Signed-off-by: Galen Charlton --- diff --git a/Open-ILS/src/templates/staff/serials/index.tt2 b/Open-ILS/src/templates/staff/serials/index.tt2 index bbb73acc03..3ae1ea8911 100644 --- a/Open-ILS/src/templates/staff/serials/index.tt2 +++ b/Open-ILS/src/templates/staff/serials/index.tt2 @@ -8,6 +8,7 @@ + [% END %] diff --git a/Open-ILS/src/templates/staff/serials/t_manage.tt2 b/Open-ILS/src/templates/staff/serials/t_manage.tt2 index f4e4a384d5..58bfc201b9 100644 --- a/Open-ILS/src/templates/staff/serials/t_manage.tt2 +++ b/Open-ILS/src/templates/staff/serials/t_manage.tt2 @@ -8,112 +8,7 @@ - -
-
-
-
- - -
-
- -
-
- -
-
- -
-
- -
-
- - -
- -
-
-
-
- - - - - - -
-
- -
-
-
-
- - -
-
-
-
-
-
-
- -
- - -
-
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+

Frequency TODO

diff --git a/Open-ILS/src/templates/staff/serials/t_subscription_manager.tt2 b/Open-ILS/src/templates/staff/serials/t_subscription_manager.tt2 new file mode 100644 index 0000000000..1c15c0ae2f --- /dev/null +++ b/Open-ILS/src/templates/staff/serials/t_subscription_manager.tt2 @@ -0,0 +1,104 @@ +
+
+
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+ +
+
+
+
+ + + + + + +
+
+ +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+ + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Open-ILS/web/js/ui/default/staff/serials/app.js b/Open-ILS/web/js/ui/default/staff/serials/app.js index c494e56101..50493a1d25 100644 --- a/Open-ILS/web/js/ui/default/staff/serials/app.js +++ b/Open-ILS/web/js/ui/default/staff/serials/app.js @@ -1,5 +1,7 @@ -angular.module('egSerialsApp', ['ui.bootstrap','ngRoute','egCoreMod','egGridMod','ngToast','egSerialsMod']) +angular.module('egSerialsApp', ['ui.bootstrap','ngRoute','egCoreMod','egGridMod','ngToast','egSerialsMod','egSerialsAppDep']); +angular.module('egSerialsAppDep', []); +angular.module('egSerialsApp') .config(['ngToastProvider', function(ngToastProvider) { ngToastProvider.configure({ verticalPosition: 'bottom', @@ -27,289 +29,8 @@ angular.module('egSerialsApp', ['ui.bootstrap','ngRoute','egCoreMod','egGridMod' }) .controller('ManageCtrl', - ['$scope','$routeParams','$location','$window','$q','egSerialsCoreSvc','egCore', - 'egGridDataProvider','$uibModal', -function($scope , $routeParams , $location , $window , $q , egSerialsCoreSvc , egCore , - egGridDataProvider , $uibModal -) { + ['$scope','$routeParams','$location', +function($scope , $routeParams , $location) { $scope.bib_id = $routeParams.bib_id; $scope.active_tab = $routeParams.active_tab ? $routeParams.active_tab : 'create-subscription'; - egSerialsCoreSvc.fetch($scope.bib_id).then(function() { - $scope.subscriptions = egCore.idl.toTypedHash(egSerialsCoreSvc.subTree); - }); - $scope.distStreamGridControls = { - activateItem : function (item) { } // TODO - }; - $scope.distStreamGridDataProvider = egGridDataProvider.instance({ - get : function(offset, count) { - return this.arrayNotifier(egSerialsCoreSvc.subList, offset, count); - } - }); - - function reload() { - egSerialsCoreSvc.fetch($scope.bib_id).then(function() { - $scope.subscriptions = egCore.idl.toTypedHash(egSerialsCoreSvc.subTree); - $scope.distStreamGridDataProvider.refresh(); - }); - } - - $scope.need_one_selected = function() { - var items = $scope.distStreamGridControls.selectedItems(); - if (items.length == 1) return false; - return true; - }; - - $scope.add_subscription = function() { - var new_ssub = egCore.idl.toTypedHash(new egCore.idl.ssub()); - new_ssub._isnew = true; - new_ssub.record_entry = $scope.bib_id; - $scope.subscriptions.push(new_ssub); - } - $scope.add_distribution = function(ssub) { - var new_sdist = egCore.idl.toTypedHash(new egCore.idl.sdist()); - new_sdist._isnew = true; - new_sdist.subscription = ssub.id; - if (!angular.isArray(ssub.distributions)){ - ssub.distributions = []; - } - ssub.distributions.push(new_sdist); - } - $scope.add_stream = function(sdist) { - var new_sstr = egCore.idl.toTypedHash(new egCore.idl.sstr()); - new_sstr.distribution = sdist.id; - new_sstr._isnew = true; - if (!angular.isArray(sdist.streams)){ - sdist.streams = []; - } - sdist.streams.push(new_sstr); - } - - $scope.abort_changes = function(form) { - reload(); - form.$setPristine(); - } - $scope.save_subscriptions = function(form) { - // traverse through structure and set _ischanged - // TODO add more granular dirty input detection - angular.forEach($scope.subscriptions, function(ssub) { - if (!ssub._isnew) ssub._ischanged = true; - angular.forEach(ssub.distributions, function(sdist) { - if (!sdist._isnew) sdist._ischanged = true; - angular.forEach(sdist.streams, function(sstr) { - if (!sstr._isnew) sstr._ischanged = true; - }); - }); - }); - - var obj = egCore.idl.fromTypedHash($scope.subscriptions); - - // create a bunch of promises that each get resolved upon each - // CUD update; that way, we can know when the entire save - // operation is completed - var promises = []; - angular.forEach(obj, function(ssub) { - ssub._cud_done = $q.defer(); - promises.push(ssub._cud_done.promise); - angular.forEach(ssub.distributions(), function(sdist) { - sdist._cud_done = $q.defer(); - promises.push(sdist._cud_done.promise); - angular.forEach(sdist.streams(), function(sstr) { - sstr._cud_done = $q.defer(); - promises.push(sstr._cud_done.promise); - }); - }); - }); - - angular.forEach(obj, function(ssub) { - ssub.owning_lib(ssub.owning_lib().id()); // deflesh - egCore.pcrud.apply(ssub).then(function(res) { - var ssub_id = (ssub.isnew() && angular.isObject(res)) ? res.id() : ssub.id(); - angular.forEach(ssub.distributions(), function(sdist) { - // set subscription ID just in case it's new - sdist.holding_lib(sdist.holding_lib().id()); // deflesh - sdist.subscription(ssub_id); - egCore.pcrud.apply(sdist).then(function(res) { - var sdist_id = (sdist.isnew() && angular.isObject(res)) ? res.id() : sdist.id(); - angular.forEach(sdist.streams(), function(sstr) { - // set distribution ID just in case it's new - sstr.distribution(sdist_id); - egCore.pcrud.apply(sstr).then(function(res) { - sstr._cud_done.resolve(); - }); - }); - }); - sdist._cud_done.resolve(); - }); - ssub._cud_done.resolve(); - }); - }); - $q.all(promises).then(function(resolutions) { - reload(); - form.$setPristine(); - }); - } - $scope.additional_routing = function(rows) { - if (!rows) { return; } - var row = rows[0]; - if (!row) { row = $scope.distStreamGridControls.selectedItems()[0]; } - if (row && row['sstr.id']) { - egCore.pcrud.search('srlu', { - stream : row['sstr.id'] - }, { - flesh : 2, - flesh_fields : { - 'srlu' : ['reader'], - 'au' : ['mailing_address','billing_address','home_ou'] - }, - order_by : { srlu : 'pos' } - }, - { atomic : true } - ).then(function(list) { - $uibModal.open({ - templateUrl: './serials/t_routing_list', - controller: 'RoutingCtrl', - resolve : { - rowInfo : function() { - return row; - }, - routes : function() { - return egCore.idl.toHash(list); - } - } - }).result.then(function(routes) { - // delete all of the routes first; - // it's easiest given the constraints - var deletions = []; - var creations = []; - angular.forEach(routes, function(r) { - var srlu = new egCore.idl.srlu(); - srlu.stream(r.stream); - srlu.pos(r.pos); - if (r.reader) { - srlu.reader(r.reader.id); - } - srlu.department(r.department); - srlu.note(r.note); - if (r.id) { - srlu.id(r.id); - var srlu_copy = angular.copy(srlu); - srlu_copy.isdeleted(true); - deletions.push(srlu_copy); - } - if (!r.delete_me) { - srlu.isnew(true); - creations.push(srlu); - } - }); - egCore.pcrud.apply(deletions.concat(creations)).then(function(){ - reload(); - }); - }); - }); - } - } -}]) - -.controller('RoutingCtrl', - ['$scope','$uibModalInstance','egCore','rowInfo','routes', -function($scope , $uibModalInstance , egCore , rowInfo , routes ) { - $scope.args = { - which_radio_button: 'reader' - ,reader: '' - ,department: '' - ,delete_me: false - }; - $scope.stream_id = rowInfo['sstr.id']; - $scope.stream_label = rowInfo['sstr.routing_label']; - $scope.routes = routes; - $scope.readerInFocus = true; - $scope.ok = function(count) { $uibModalInstance.close($scope.routes) } - $scope.cancel = function () { $uibModalInstance.dismiss() } - $scope.model_has_changed = false; - $scope.find_user = function () { - - $scope.readerNotFound = null; - $scope.reader_obj = null; - if (!$scope.args.reader) return; - - egCore.net.request( - 'open-ils.actor', - 'open-ils.actor.get_barcodes', - egCore.auth.token(), egCore.auth.user().ws_ou(), - 'actor', $scope.args.reader) - - .then(function(resp) { // get_barcodes - - if (evt = egCore.evt.parse(resp)) { - console.error(evt.toString()); - return; - } - - if (!resp || !resp[0]) { - $scope.readerNotFound = $scope.args.reader; - return; - } - - egCore.pcrud.search('au', { - id : resp[0].id - }, { - flesh : 1, - flesh_fields : { - 'au' : ['mailing_address','billing_address','home_ou'] - } - }, - { atomic : true } - ).then(function(usr) { - $scope.reader_obj = egCore.idl.toHash(usr[0]); - }); - }); - } - $scope.add_route = function () { - var new_route = { - stream: $scope.stream_id - ,pos: $scope.routes.length - ,note: $scope.args.note - } - if ($scope.args.which_radio_button == 'reader') { - new_route.reader = $scope.reader_obj; - } else { - new_route.department = $scope.args.department; - } - $scope.routes.push(new_route); - $scope.model_has_changed = true; - } - function adjust_pos_field() { - var idx = 0; - for (var i = 0; i < $scope.routes.length; i++) { - $scope.routes[i].pos = $scope.routes[i].delete_me ? idx : idx++; - } - $scope.model_has_changed = true; - } - $scope.move_route_up = function(r) { - var pos = r.pos; - if (pos > 0) { - var temp = $scope.routes[ pos - 1 ]; - $scope.routes[ pos - 1 ] = $scope.routes[ pos ]; - $scope.routes[ pos ] = temp; - adjust_pos_field(); - } - } - $scope.move_route_down = function(r) { - var pos = r.pos; - if (pos < $scope.routes.length - 1) { - var temp = $scope.routes[ pos + 1 ]; - $scope.routes[ pos + 1 ] = $scope.routes[ pos ]; - $scope.routes[ pos ] = temp; - adjust_pos_field(); - } - } - $scope.toggle_delete = function(r) { - r.delete_me = ! r.delete_me; - adjust_pos_field(); - } - $scope.$watch("args.reader", function(newVal, oldVal) { - if (newVal && newVal != oldVal) { - $scope.find_user(); - } - }); }]) diff --git a/Open-ILS/web/js/ui/default/staff/serials/directives/subscription_manager.js b/Open-ILS/web/js/ui/default/staff/serials/directives/subscription_manager.js new file mode 100644 index 0000000000..fb983ec589 --- /dev/null +++ b/Open-ILS/web/js/ui/default/staff/serials/directives/subscription_manager.js @@ -0,0 +1,296 @@ +angular.module('egSerialsAppDep') + +.directive('egSubscriptionManager', function() { + return { + transclude: true, + restrict: 'E', + scope: { + bibId : '=' + }, + templateUrl: './serials/t_subscription_manager', + controller: + ['$scope','$q','egSerialsCoreSvc','egCore','egGridDataProvider', + '$uibModal', + function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider , + $uibModal) { + egSerialsCoreSvc.fetch($scope.bibId).then(function() { + $scope.subscriptions = egCore.idl.toTypedHash(egSerialsCoreSvc.subTree); + }); + $scope.distStreamGridControls = { + activateItem : function (item) { } // TODO + }; + $scope.distStreamGridDataProvider = egGridDataProvider.instance({ + get : function(offset, count) { + return this.arrayNotifier(egSerialsCoreSvc.subList, offset, count); + } + }); + + function reload() { + egSerialsCoreSvc.fetch($scope.bibId).then(function() { + $scope.subscriptions = egCore.idl.toTypedHash(egSerialsCoreSvc.subTree); + $scope.distStreamGridDataProvider.refresh(); + }); + } + + $scope.need_one_selected = function() { + var items = $scope.distStreamGridControls.selectedItems(); + if (items.length == 1) return false; + return true; + }; + + $scope.add_subscription = function() { + var new_ssub = egCore.idl.toTypedHash(new egCore.idl.ssub()); + new_ssub._isnew = true; + new_ssub.record_entry = $scope.bibId; + $scope.subscriptions.push(new_ssub); + } + $scope.add_distribution = function(ssub) { + var new_sdist = egCore.idl.toTypedHash(new egCore.idl.sdist()); + new_sdist._isnew = true; + new_sdist.subscription = ssub.id; + if (!angular.isArray(ssub.distributions)){ + ssub.distributions = []; + } + ssub.distributions.push(new_sdist); + } + $scope.add_stream = function(sdist) { + var new_sstr = egCore.idl.toTypedHash(new egCore.idl.sstr()); + new_sstr.distribution = sdist.id; + new_sstr._isnew = true; + if (!angular.isArray(sdist.streams)){ + sdist.streams = []; + } + sdist.streams.push(new_sstr); + } + + $scope.abort_changes = function(form) { + reload(); + form.$setPristine(); + } + $scope.save_subscriptions = function(form) { + // traverse through structure and set _ischanged + // TODO add more granular dirty input detection + angular.forEach($scope.subscriptions, function(ssub) { + if (!ssub._isnew) ssub._ischanged = true; + angular.forEach(ssub.distributions, function(sdist) { + if (!sdist._isnew) sdist._ischanged = true; + angular.forEach(sdist.streams, function(sstr) { + if (!sstr._isnew) sstr._ischanged = true; + }); + }); + }); + + var obj = egCore.idl.fromTypedHash($scope.subscriptions); + + // create a bunch of promises that each get resolved upon each + // CUD update; that way, we can know when the entire save + // operation is completed + var promises = []; + angular.forEach(obj, function(ssub) { + ssub._cud_done = $q.defer(); + promises.push(ssub._cud_done.promise); + angular.forEach(ssub.distributions(), function(sdist) { + sdist._cud_done = $q.defer(); + promises.push(sdist._cud_done.promise); + angular.forEach(sdist.streams(), function(sstr) { + sstr._cud_done = $q.defer(); + promises.push(sstr._cud_done.promise); + }); + }); + }); + + angular.forEach(obj, function(ssub) { + ssub.owning_lib(ssub.owning_lib().id()); // deflesh + egCore.pcrud.apply(ssub).then(function(res) { + var ssub_id = (ssub.isnew() && angular.isObject(res)) ? res.id() : ssub.id(); + angular.forEach(ssub.distributions(), function(sdist) { + // set subscription ID just in case it's new + sdist.holding_lib(sdist.holding_lib().id()); // deflesh + sdist.subscription(ssub_id); + egCore.pcrud.apply(sdist).then(function(res) { + var sdist_id = (sdist.isnew() && angular.isObject(res)) ? res.id() : sdist.id(); + angular.forEach(sdist.streams(), function(sstr) { + // set distribution ID just in case it's new + sstr.distribution(sdist_id); + egCore.pcrud.apply(sstr).then(function(res) { + sstr._cud_done.resolve(); + }); + }); + }); + sdist._cud_done.resolve(); + }); + ssub._cud_done.resolve(); + }); + }); + $q.all(promises).then(function(resolutions) { + reload(); + form.$setPristine(); + }); + } + $scope.additional_routing = function(rows) { + if (!rows) { return; } + var row = rows[0]; + if (!row) { row = $scope.distStreamGridControls.selectedItems()[0]; } + if (row && row['sstr.id']) { + egCore.pcrud.search('srlu', { + stream : row['sstr.id'] + }, { + flesh : 2, + flesh_fields : { + 'srlu' : ['reader'], + 'au' : ['mailing_address','billing_address','home_ou'] + }, + order_by : { srlu : 'pos' } + }, + { atomic : true } + ).then(function(list) { + $uibModal.open({ + templateUrl: './serials/t_routing_list', + controller: 'RoutingCtrl', + resolve : { + rowInfo : function() { + return row; + }, + routes : function() { + return egCore.idl.toHash(list); + } + } + }).result.then(function(routes) { + // delete all of the routes first; + // it's easiest given the constraints + var deletions = []; + var creations = []; + angular.forEach(routes, function(r) { + var srlu = new egCore.idl.srlu(); + srlu.stream(r.stream); + srlu.pos(r.pos); + if (r.reader) { + srlu.reader(r.reader.id); + } + srlu.department(r.department); + srlu.note(r.note); + if (r.id) { + srlu.id(r.id); + var srlu_copy = angular.copy(srlu); + srlu_copy.isdeleted(true); + deletions.push(srlu_copy); + } + if (!r.delete_me) { + srlu.isnew(true); + creations.push(srlu); + } + }); + egCore.pcrud.apply(deletions.concat(creations)).then(function(){ + reload(); + }); + }); + }); + } + } + }] + } +}) + +.controller('RoutingCtrl', + ['$scope','$uibModalInstance','egCore','rowInfo','routes', +function($scope , $uibModalInstance , egCore , rowInfo , routes ) { + $scope.args = { + which_radio_button: 'reader' + ,reader: '' + ,department: '' + ,delete_me: false + }; + $scope.stream_id = rowInfo['sstr.id']; + $scope.stream_label = rowInfo['sstr.routing_label']; + $scope.routes = routes; + $scope.readerInFocus = true; + $scope.ok = function(count) { $uibModalInstance.close($scope.routes) } + $scope.cancel = function () { $uibModalInstance.dismiss() } + $scope.model_has_changed = false; + $scope.find_user = function () { + + $scope.readerNotFound = null; + $scope.reader_obj = null; + if (!$scope.args.reader) return; + + egCore.net.request( + 'open-ils.actor', + 'open-ils.actor.get_barcodes', + egCore.auth.token(), egCore.auth.user().ws_ou(), + 'actor', $scope.args.reader) + + .then(function(resp) { // get_barcodes + + if (evt = egCore.evt.parse(resp)) { + console.error(evt.toString()); + return; + } + + if (!resp || !resp[0]) { + $scope.readerNotFound = $scope.args.reader; + return; + } + + egCore.pcrud.search('au', { + id : resp[0].id + }, { + flesh : 1, + flesh_fields : { + 'au' : ['mailing_address','billing_address','home_ou'] + } + }, + { atomic : true } + ).then(function(usr) { + $scope.reader_obj = egCore.idl.toHash(usr[0]); + }); + }); + } + $scope.add_route = function () { + var new_route = { + stream: $scope.stream_id + ,pos: $scope.routes.length + ,note: $scope.args.note + } + if ($scope.args.which_radio_button == 'reader') { + new_route.reader = $scope.reader_obj; + } else { + new_route.department = $scope.args.department; + } + $scope.routes.push(new_route); + $scope.model_has_changed = true; + } + function adjust_pos_field() { + var idx = 0; + for (var i = 0; i < $scope.routes.length; i++) { + $scope.routes[i].pos = $scope.routes[i].delete_me ? idx : idx++; + } + $scope.model_has_changed = true; + } + $scope.move_route_up = function(r) { + var pos = r.pos; + if (pos > 0) { + var temp = $scope.routes[ pos - 1 ]; + $scope.routes[ pos - 1 ] = $scope.routes[ pos ]; + $scope.routes[ pos ] = temp; + adjust_pos_field(); + } + } + $scope.move_route_down = function(r) { + var pos = r.pos; + if (pos < $scope.routes.length - 1) { + var temp = $scope.routes[ pos + 1 ]; + $scope.routes[ pos + 1 ] = $scope.routes[ pos ]; + $scope.routes[ pos ] = temp; + adjust_pos_field(); + } + } + $scope.toggle_delete = function(r) { + r.delete_me = ! r.delete_me; + adjust_pos_field(); + } + $scope.$watch("args.reader", function(newVal, oldVal) { + if (newVal && newVal != oldVal) { + $scope.find_user(); + } + }); +}])