]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/admin/local/permission/app.js
8c5d73f8cae1c44f60121fba2eb5278b7ae70b65
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / admin / local / permission / app.js
1 angular.module('egAdminPermGrpTreeApp',
2     ['ngRoute','ui.bootstrap','egCoreMod','egUiMod','treeControl'])
3
4 .config(function($routeProvider, $locationProvider, $compileProvider) {
5     $locationProvider.html5Mode(true);
6     $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/);
7
8     var resolver = {delay :
9         ['egStartup', function(egStartup) {return egStartup.go()}]}
10
11     $routeProvider.when('/admin/local/permission/grp_tree_display_entry', {
12         templateUrl : './admin/local/permission/t_grp_tree_display_entry',
13         controller : 'PermGrpTreeCtrl',
14         resolve : resolver
15     });
16
17     $routeProvider.otherwise({redirectTo : '/admin/local/permission/grp_tree'});
18 })
19
20 .factory('egPermGrpTreeSvc',
21         ['$q','egCore', function($q , egCore) {
22     var service = {
23         pgtde_array: [],
24         display_entries: [],
25         disabled_entries: [],
26         profiles: [],
27         edit_profiles: []
28     };
29
30     // determine which user groups our user is not allowed to modify
31     service.set_edit_profiles = function() {
32         var all_app_perms = [];
33         var failed_perms = [];
34
35         // extract the application permissions
36         angular.forEach(service.profiles, function(grp) {
37             if (grp.application_perm())
38                 all_app_perms.push(grp.application_perm());
39         }); 
40
41         // fill in service.edit_profiles by inspecting failed_perms
42         function traverse_grp_tree(grp, failed) {
43             failed = failed || 
44                 failed_perms.indexOf(grp.application_perm()) > -1;
45
46             if (!failed) service.edit_profiles.push(grp);
47
48             angular.forEach(
49                 service.profiles.filter( // children of grp
50                     function(p) { return p.parent() == grp.id() }),
51                 function(child) {traverse_grp_tree(child, failed)}
52             );
53         }
54
55         return egCore.perm.hasPermAt(all_app_perms, true).then(
56             function(perm_orgs) {
57                 angular.forEach(all_app_perms, function(p) {
58                     if (perm_orgs[p].length == 0)
59                         failed_perms.push(p);
60                 });
61
62                 traverse_grp_tree(egCore.env.pgt.tree);
63             }
64         );
65     }
66
67     service.get_perm_groups = function() {
68         if (egCore.env.pgt) {
69             service.profiles = egCore.env.pgt.list;
70             return service.set_edit_profiles();
71         } else {
72             return egCore.pcrud.search('pgt', {parent : null}, 
73                 {flesh : -1, flesh_fields : {pgt : ['children']}}
74             ).then(
75                 function(tree) {
76                     egCore.env.absorbTree(tree, 'pgt')
77                     service.profiles = egCore.env.pgt.list;
78                     return service.set_edit_profiles();
79                 }
80             );
81         }
82     }
83
84     service.fetchDisplayEntries = function(ou_id) {
85         service.edit_profiles = [];
86         service.get_perm_groups();
87         return egCore.pcrud.search('pgtde',
88             {org : egCore.org.ancestors(ou_id, true)},
89             { flesh : 1,
90               flesh_fields : {
91                   pgtde: ['grp', 'org']
92               },
93               order_by: {pgtde : 'id'}
94             },
95             {atomic: true}
96         ).then(function(entries) {
97             service.pgtde_array = [];
98             service.disabled_entries = [];
99             angular.forEach(entries, function(entry) {
100                 if (entry.disabled() == 'f') {
101                     entry.disabled(false);
102                     service.pgtde_array.push(entry);
103                 }
104                 if (entry.disabled() == 't') {
105                     entry.disabled(true);
106                     service.disabled_entries.push(entry);
107                 }
108             });
109         });
110     }
111
112     service.organizeDisplayEntries = function(selectedOrg) {
113         service.display_entries = [];
114
115         angular.forEach(service.pgtde_array, function(pgtde) {
116             if (pgtde.org().id() == selectedOrg) {
117                 if (!pgtde.child_entries) pgtde.child_entries = [];
118                 var isChild = false;
119                 angular.forEach(service.display_entries, function(entry) {
120                     if (pgtde.parent() && pgtde.parent() == entry.id()) {
121                         entry.child_entries.push(pgtde);
122                         isChild = true;
123                         return;
124                     } else {
125                         if (service.iterateChildEntries(pgtde, entry)) {
126                             isChild = true;
127                             return;
128                         }
129                     }
130                 });
131                 if (!pgtde.parent() || !isChild) {
132                     service.display_entries.push(pgtde);
133                 }
134             }
135         });
136     }
137
138     service.iterateChildEntries = function(pgtde, entry) {
139         if (entry.child_entries.length) {
140             return angular.forEach(entry.child_entries, function(child) {
141                 if (pgtde.parent() == child.id()) {
142                     child.child_entries.push(pgtde);
143                     return true;
144                 } else {
145                     return service.iterateChildEntries(pgtde, child);
146                 }
147             });
148         }
149     }
150
151     service.updateDisplayEntries = function(tree, ou_id) {
152         return egCore.pcrud.search('pgtde',
153             {org : ou_id},
154             { flesh : 1,
155               flesh_fields : {
156                   pgtde: ['grp', 'org']
157               },
158               order_by: {pgtde : 'id'}
159             },
160             {atomic: true}
161         ).then(function(entries) {
162             return egCore.pcrud.update(tree).then(function(res) {
163                 return res;
164             });
165         });
166     }
167
168     service.removeDisplayEntries = function(entries) {
169         return egCore.pcrud.remove(entries).then(function(res) {
170             return res;
171         });
172     }
173
174     service.addDisplayEntries = function(entries) {
175         return egCore.pcrud.create(entries).then(function(res) {
176             return res;
177         });
178     }
179
180     service.findEntry = function(id, entries) {
181         var match;
182         angular.forEach(entries, function(entry) {
183             if (!match) {
184                 if (!entry.child_entries) entry.child_entries = [];
185                 if (id == entry.id()) {
186                     match = entry;
187                 } else if (entry.child_entries.length) {
188                     match = service.findEntry(id, entry.child_entries);
189                 }
190             }
191         });
192
193         return match;
194     }
195
196     return service;
197 }])
198
199 .controller('PermGrpTreeCtrl',
200     ['$scope','$q','$timeout','$location','$uibModal','egCore','egPermGrpTreeSvc', 'ngToast', 'egProgressDialog',
201 function($scope , $q , $timeout , $location , $uibModal , egCore , egPermGrpTreeSvc, ngToast, egProgressDialog) {
202     $scope.perm_tree = [{
203         grp: function() {
204             return {
205                 name: function() {return egCore.strings.ROOT_NODE_NAME;}
206             }
207         },
208         child_entries: [],
209         permanent: 'true'
210     }];
211     $scope.display_entries = [];
212     $scope.new_entries = [];
213     $scope.tree_options = {nodeChildren: 'child_entries'};
214     $scope.selected_entry;
215     $scope.expanded_nodes = [];
216     $scope.orderby = ['position()','grp().name()'];
217
218     if (!$scope.selectedOrg)
219         $scope.selectedOrg = egCore.org.get(egCore.auth.user().ws_ou());
220
221     $scope.updateSelection = function(node, selected) {
222         $scope.selected_entry = node;
223         if (!selected) $scope.selected_entry = null;
224     }
225
226     $scope.setPosition = function(node, direction) {
227         var newPos = node.position();
228         var siblings;
229         if (node.parent()) {
230             siblings = egPermGrpTreeSvc.findEntry(node.parent(), $scope.perm_tree[0].child_entries).child_entries;
231         } else {
232             siblings = $scope.perm_tree[0].child_entries;
233         }
234         if (direction == 'up' && newPos < siblings.length) newPos++;
235         if (direction == 'down' && newPos > 1) newPos--;
236
237         angular.forEach(siblings, function(entry) {
238             if (entry.position() == newPos) entry.position(node.position());
239             angular.forEach($scope.display_entries, function(display_entry) {
240                 if (display_entry.id() == entry.id()) {
241                     if (display_entry.position() == newPos) {
242                         display_entry.position(node.position);
243                     };
244                 }
245             });
246         });
247
248         angular.forEach($scope.display_entries, function(display_entry) {
249             if (display_entry.id() == node.id()) {
250                 display_entry.position(newPos);
251             }
252         });
253
254         node.position(newPos);
255     }
256
257     $scope.addChildEntry = function(node) {
258
259         $scope.openAddDialog(node, $scope.disabled_entries, $scope.edit_profiles, $scope.display_entries, $scope.selectedOrg)
260         .then(function(res) {
261             if (res) {
262
263                 var siblings = []
264                 var new_entry = new egCore.idl.pgtde();
265                 new_entry.org($scope.selectedOrg.id());
266                 new_entry.grp(res.selected_grp);
267                 new_entry.position(1);
268                 new_entry.child_entries = [];
269                 var is_expanded;
270                 if (res.selected_parent) {
271                     new_entry.parent(res.selected_parent);
272                     angular.forEach($scope.expanded_nodes, function(expanded_node) {
273                         if (expanded_node == res.selected_parent) is_expanded = true;
274                     });
275                     if (!is_expanded) $scope.expanded_nodes.push(res.selected_parent);
276                 } else {
277                     angular.forEach($scope.expanded_nodes, function(expanded_node) {
278                         if (expanded_node == $scope.perm_tree[0]) is_expanded = true;
279                     });
280                     if (!is_expanded) $scope.expanded_nodes.push($scope.perm_tree[0]);
281                 }
282
283                 $scope.display_entries.push(new_entry);
284                 egPermGrpTreeSvc.addDisplayEntries([new_entry]).then(function(addRes) {
285                     if (addRes) {
286                         if (res.is_root || !res.selected_parent) {
287                             angular.forEach($scope.perm_tree[0].child_entries, function(entry) {
288                                 var newPos = entry.position();
289                                 newPos++;
290                                 entry.position(newPos);
291                                 siblings.push(entry);
292                             });
293                         } else {
294                             var parent = egPermGrpTreeSvc.findEntry(res.selected_parent.id(), $scope.perm_tree[0].child_entries);
295                             angular.forEach(parent.child_entries, function(entry) {
296                                 var newPos = entry.position();
297                                 newPos++;
298                                 entry.position(newPos);
299                                 siblings.push(entry);
300                             });
301                         }
302
303                         egPermGrpTreeSvc.updateDisplayEntries(siblings).then(function(updateRes) {
304                             ngToast.create(egCore.strings.ADD_SUCCESS);
305                             $scope.refreshTree($scope.selectedOrg, $scope.selected_entry);
306                         });
307                     } else {
308                         ngToast.create(egCore.strings.ADD_FAILURE);
309                     }
310                 });
311             }
312         });
313     }
314
315     $scope.openAddDialog = function(node, disabled_entries, edit_profiles, display_entries, selected_org) {
316
317         return $uibModal.open({
318             templateUrl : './admin/local/permission/t_pgtde_add_dialog',
319             backdrop: 'static',
320             controller : [
321                         '$scope','$uibModalInstance',
322                 function($scope , $uibModalInstance) {
323                     var getIsRoot = function() {
324                         if (!node || node.permanent) return true;
325                         return false;
326                     }
327
328                     var getSelectedParent = function() {
329                         if (!node || node.permanent) return $scope.perm_tree;
330                         return node;
331                     }
332
333                     var available_profiles = [];
334                     angular.forEach(edit_profiles, function(grp) {
335                         grp._filter_grp = false;
336                         angular.forEach(display_entries, function(entry) {
337                             if (entry.org().id() == selected_org.id()) {
338                                 if (entry.grp().id() == grp.id()) grp._filter_grp = true;
339                             }
340                         });
341                         if (!grp._filter_grp) available_profiles.push(grp);
342                     });
343
344                     $scope.context = {
345                         is_root : getIsRoot(),
346                         selected_parent : getSelectedParent(),
347                         edit_profiles : available_profiles,
348                         display_entries : display_entries,
349                         selected_org : selected_org
350                     }
351
352                     $scope.context.selected_grp = $scope.context.edit_profiles[0];
353
354                     $scope.ok = function() {
355                         $uibModalInstance.close($scope.context);
356                     }
357
358                     $scope.cancel = function() {
359                         $uibModalInstance.dismiss();
360                     }
361                 }
362             ]
363         }).result;
364     }
365
366     var iteratePermTree = function(arr1, arr2) {
367         angular.forEach(arr1, function(entry) {
368             arr2.push(entry);
369             if (entry.child_entries) iteratePermTree(entry.child_entries, arr2);
370         });
371     }
372
373     $scope.removeEntry = function(node) {
374         $scope.disabled_entries.push(node);
375         iteratePermTree(node.child_entries, $scope.disabled_entries);
376
377         var siblings;
378         if (node.parent()) {
379             siblings = egPermGrpTreeSvc.findEntry(node.parent(), $scope.perm_tree[0].child_entries).child_entries;
380         } else {
381             siblings = $scope.perm_tree[0].child_entries;
382         }
383         angular.forEach(siblings, function(sibling) {
384             var newPos = sibling.position();
385             if (node.position() < sibling.position()) {
386                 newPos--;
387             }
388             sibling.position(newPos);
389         });
390
391         $scope.selected_entry = null;
392
393         egPermGrpTreeSvc.removeDisplayEntries($scope.disabled_entries).then(function(res) {
394             if (res) {
395                 ngToast.create(egCore.strings.REMOVE_SUCCESS);
396                 $scope.refreshTree($scope.selectedOrg);
397             } else {
398                 ngToast.create(egCore.strings.REMOVE_FAILURE);
399             }
400         })
401     }
402
403     var getDisplayEntries = function() {
404         $scope.edit_profiles = egPermGrpTreeSvc.edit_profiles;
405         egPermGrpTreeSvc.organizeDisplayEntries($scope.selectedOrg.id());
406         $scope.perm_tree[0].child_entries = egPermGrpTreeSvc.display_entries;
407         $scope.display_entries = egPermGrpTreeSvc.pgtde_array;
408         $scope.new_entries = [];
409         $scope.disabled_entries = [];
410         $scope.selected_entry = $scope.perm_tree[0];
411         if (!$scope.expanded_nodes.length) iteratePermTree($scope.perm_tree, $scope.expanded_nodes);
412     }
413
414     $scope.saveEntries = function() {
415         egProgressDialog.open();
416
417         // Save Remaining Display Entries
418         egPermGrpTreeSvc.updateDisplayEntries($scope.display_entries, $scope.selectedOrg.id())
419         .then(function(res) {
420             if (res) {
421                 ngToast.create(egCore.strings.UPDATE_SUCCESS);
422                 $scope.refreshTree($scope.selectedOrg, $scope.selected_entry);
423             } else {
424                 ngToast.create(egCore.strings.UPDATE_FAILURE);
425             }
426         }).finally(egProgressDialog.close);
427     }
428
429     $scope.org_changed = function(org) {
430         $scope.refreshTree(org.id());
431     }
432
433     $scope.refreshTree = function(ou_id, node) {
434         egPermGrpTreeSvc.fetchDisplayEntries(ou_id).then(function() {
435             getDisplayEntries();
436             if (node) $scope.selected_entry = node;
437         });
438     }
439
440     egCore.startup.go(function() {
441         $scope.refreshTree(egCore.auth.user().ws_ou());
442     });
443 }])