]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/admin/local/permission/app.js
lp1744756 Docs fix and Permission change
[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                 service.pgtde_array.push(entry);
101             });
102         });
103     }
104
105     service.organizeDisplayEntries = function(selectedOrg) {
106         service.display_entries = [];
107
108         angular.forEach(service.pgtde_array, function(pgtde) {
109             if (pgtde.org().id() == selectedOrg) {
110                 if (!pgtde.child_entries) pgtde.child_entries = [];
111                 var isChild = false;
112                 angular.forEach(service.display_entries, function(entry) {
113                     if (pgtde.parent() && pgtde.parent() == entry.id()) {
114                         entry.child_entries.push(pgtde);
115                         isChild = true;
116                         return;
117                     } else {
118                         if (service.iterateChildEntries(pgtde, entry)) {
119                             isChild = true;
120                             return;
121                         }
122                     }
123                 });
124                 if (!pgtde.parent() || !isChild) {
125                     service.display_entries.push(pgtde);
126                 }
127             }
128         });
129     }
130
131     service.iterateChildEntries = function(pgtde, entry) {
132         if (entry.child_entries.length) {
133             return angular.forEach(entry.child_entries, function(child) {
134                 if (pgtde.parent() == child.id()) {
135                     child.child_entries.push(pgtde);
136                     return true;
137                 } else {
138                     return service.iterateChildEntries(pgtde, child);
139                 }
140             });
141         }
142     }
143
144     service.updateDisplayEntries = function(tree, ou_id) {
145         return egCore.pcrud.search('pgtde',
146             {org : ou_id},
147             { flesh : 1,
148               flesh_fields : {
149                   pgtde: ['grp', 'org']
150               },
151               order_by: {pgtde : 'id'}
152             },
153             {atomic: true}
154         ).then(function(entries) {
155             return egCore.pcrud.update(tree).then(function(res) {
156                 return res;
157             });
158         });
159     }
160
161     service.removeDisplayEntries = function(entries) {
162         return egCore.pcrud.remove(entries).then(function(res) {
163             return res;
164         });
165     }
166
167     service.addDisplayEntries = function(entries) {
168         return egCore.pcrud.create(entries).then(function(res) {
169             return res;
170         });
171     }
172
173     service.findEntry = function(id, entries) {
174         var match;
175         angular.forEach(entries, function(entry) {
176             if (!match) {
177                 if (!entry.child_entries) entry.child_entries = [];
178                 if (id == entry.id()) {
179                     match = entry;
180                 } else if (entry.child_entries.length) {
181                     match = service.findEntry(id, entry.child_entries);
182                 }
183             }
184         });
185
186         return match;
187     }
188
189     return service;
190 }])
191
192 .controller('PermGrpTreeCtrl',
193     ['$scope','$q','$timeout','$location','$uibModal','egCore','egPermGrpTreeSvc', 'ngToast', 'egProgressDialog',
194 function($scope , $q , $timeout , $location , $uibModal , egCore , egPermGrpTreeSvc, ngToast, egProgressDialog) {
195     $scope.perm_tree = [{
196         grp: function() {
197             return {
198                 name: function() {return egCore.strings.ROOT_NODE_NAME;}
199             }
200         },
201         child_entries: [],
202         permanent: 'true'
203     }];
204     $scope.display_entries = [];
205     $scope.new_entries = [];
206     $scope.tree_options = {nodeChildren: 'child_entries'};
207     $scope.selected_entry;
208     $scope.expanded_nodes = [];
209     $scope.orderby = ['position()','grp().name()'];
210
211     if (!$scope.selectedOrg)
212         $scope.selectedOrg = egCore.org.get(egCore.auth.user().ws_ou());
213
214     $scope.updateSelection = function(node, selected) {
215         $scope.selected_entry = node;
216         if (!selected) $scope.selected_entry = null;
217     }
218
219     $scope.setPosition = function(node, direction) {
220         var newPos = node.position();
221         var siblings;
222         if (node.parent()) {
223             siblings = egPermGrpTreeSvc.findEntry(node.parent(), $scope.perm_tree[0].child_entries).child_entries;
224         } else {
225             siblings = $scope.perm_tree[0].child_entries;
226         }
227         if (direction == 'up' && newPos < siblings.length) newPos++;
228         if (direction == 'down' && newPos > 1) newPos--;
229
230         angular.forEach(siblings, function(entry) {
231             if (entry.position() == newPos) entry.position(node.position());
232             angular.forEach($scope.display_entries, function(display_entry) {
233                 if (display_entry.id() == entry.id()) {
234                     if (display_entry.position() == newPos) {
235                         display_entry.position(node.position);
236                     };
237                 }
238             });
239         });
240
241         angular.forEach($scope.display_entries, function(display_entry) {
242             if (display_entry.id() == node.id()) {
243                 display_entry.position(newPos);
244             }
245         });
246
247         node.position(newPos);
248     }
249
250     $scope.addChildEntry = function(node) {
251
252         $scope.openAddDialog(node, $scope.disabled_entries, $scope.edit_profiles, $scope.display_entries, $scope.selectedOrg)
253         .then(function(res) {
254             if (res) {
255
256                 var siblings = []
257                 var new_entry = new egCore.idl.pgtde();
258                 new_entry.org($scope.selectedOrg.id());
259                 new_entry.grp(res.selected_grp);
260                 new_entry.position(1);
261                 new_entry.child_entries = [];
262                 var is_expanded;
263                 if (res.selected_parent) {
264                     new_entry.parent(res.selected_parent);
265                     angular.forEach($scope.expanded_nodes, function(expanded_node) {
266                         if (expanded_node == res.selected_parent) is_expanded = true;
267                     });
268                     if (!is_expanded) $scope.expanded_nodes.push(res.selected_parent);
269                 } else {
270                     angular.forEach($scope.expanded_nodes, function(expanded_node) {
271                         if (expanded_node == $scope.perm_tree[0]) is_expanded = true;
272                     });
273                     if (!is_expanded) $scope.expanded_nodes.push($scope.perm_tree[0]);
274                 }
275
276                 $scope.display_entries.push(new_entry);
277                 egPermGrpTreeSvc.addDisplayEntries([new_entry]).then(function(addRes) {
278                     if (addRes) {
279                         if (res.is_root || !res.selected_parent) {
280                             angular.forEach($scope.perm_tree[0].child_entries, function(entry) {
281                                 var newPos = entry.position();
282                                 newPos++;
283                                 entry.position(newPos);
284                                 siblings.push(entry);
285                             });
286                         } else {
287                             var parent = egPermGrpTreeSvc.findEntry(res.selected_parent.id(), $scope.perm_tree[0].child_entries);
288                             angular.forEach(parent.child_entries, function(entry) {
289                                 var newPos = entry.position();
290                                 newPos++;
291                                 entry.position(newPos);
292                                 siblings.push(entry);
293                             });
294                         }
295
296                         egPermGrpTreeSvc.updateDisplayEntries(siblings).then(function(updateRes) {
297                             ngToast.create(egCore.strings.ADD_SUCCESS);
298                             $scope.refreshTree($scope.selectedOrg, $scope.selected_entry);
299                         });
300                     } else {
301                         ngToast.create(egCore.strings.ADD_FAILURE);
302                     }
303                 });
304             }
305         });
306     }
307
308     $scope.openAddDialog = function(node, disabled_entries, edit_profiles, display_entries, selected_org) {
309
310         return $uibModal.open({
311             templateUrl : './admin/local/permission/t_pgtde_add_dialog',
312             backdrop: 'static',
313             controller : [
314                         '$scope','$uibModalInstance',
315                 function($scope , $uibModalInstance) {
316                     var getIsRoot = function() {
317                         if (!node || node.permanent) return true;
318                         return false;
319                     }
320
321                     var getSelectedParent = function() {
322                         if (!node || node.permanent) return $scope.perm_tree;
323                         return node;
324                     }
325
326                     var available_profiles = [];
327                     angular.forEach(edit_profiles, function(grp) {
328                         grp._filter_grp = false;
329                         angular.forEach(display_entries, function(entry) {
330                             if (entry.org().id() == selected_org.id()) {
331                                 if (entry.grp().id() == grp.id()) grp._filter_grp = true;
332                             }
333                         });
334                         if (!grp._filter_grp) available_profiles.push(grp);
335                     });
336
337                     $scope.context = {
338                         is_root : getIsRoot(),
339                         selected_parent : getSelectedParent(),
340                         edit_profiles : available_profiles,
341                         display_entries : display_entries,
342                         selected_org : selected_org
343                     }
344
345                     $scope.context.selected_grp = $scope.context.edit_profiles[0];
346
347                     $scope.ok = function() {
348                         $uibModalInstance.close($scope.context);
349                     }
350
351                     $scope.cancel = function() {
352                         $uibModalInstance.dismiss();
353                     }
354                 }
355             ]
356         }).result;
357     }
358
359     var iteratePermTree = function(arr1, arr2) {
360         angular.forEach(arr1, function(entry) {
361             arr2.push(entry);
362             if (entry.child_entries) iteratePermTree(entry.child_entries, arr2);
363         });
364     }
365
366     $scope.removeEntry = function(node) {
367         $scope.disabled_entries.push(node);
368         iteratePermTree(node.child_entries, $scope.disabled_entries);
369
370         var siblings;
371         if (node.parent()) {
372             siblings = egPermGrpTreeSvc.findEntry(node.parent(), $scope.perm_tree[0].child_entries).child_entries;
373         } else {
374             siblings = $scope.perm_tree[0].child_entries;
375         }
376         angular.forEach(siblings, function(sibling) {
377             var newPos = sibling.position();
378             if (node.position() < sibling.position()) {
379                 newPos--;
380             }
381             sibling.position(newPos);
382         });
383
384         $scope.selected_entry = null;
385
386         egPermGrpTreeSvc.removeDisplayEntries($scope.disabled_entries).then(function(res) {
387             if (res) {
388                 ngToast.create(egCore.strings.REMOVE_SUCCESS);
389                 $scope.refreshTree($scope.selectedOrg);
390             } else {
391                 ngToast.create(egCore.strings.REMOVE_FAILURE);
392             }
393         })
394     }
395
396     var getDisplayEntries = function() {
397         $scope.edit_profiles = egPermGrpTreeSvc.edit_profiles;
398         egPermGrpTreeSvc.organizeDisplayEntries($scope.selectedOrg.id());
399         $scope.perm_tree[0].child_entries = egPermGrpTreeSvc.display_entries;
400         $scope.display_entries = egPermGrpTreeSvc.pgtde_array;
401         $scope.new_entries = [];
402         $scope.disabled_entries = [];
403         $scope.selected_entry = $scope.perm_tree[0];
404         if (!$scope.expanded_nodes.length) iteratePermTree($scope.perm_tree, $scope.expanded_nodes);
405     }
406
407     $scope.saveEntries = function() {
408         egProgressDialog.open();
409
410         // Save Remaining Display Entries
411         egPermGrpTreeSvc.updateDisplayEntries($scope.display_entries, $scope.selectedOrg.id())
412         .then(function(res) {
413             if (res) {
414                 ngToast.create(egCore.strings.UPDATE_SUCCESS);
415                 $scope.refreshTree($scope.selectedOrg, $scope.selected_entry);
416             } else {
417                 ngToast.create(egCore.strings.UPDATE_FAILURE);
418             }
419         }).finally(egProgressDialog.close);
420     }
421
422     $scope.org_changed = function(org) {
423         $scope.refreshTree(org.id());
424     }
425
426     $scope.refreshTree = function(ou_id, node) {
427         egPermGrpTreeSvc.fetchDisplayEntries(ou_id).then(function() {
428             getDisplayEntries();
429             if (node) $scope.selected_entry = node;
430         });
431     }
432
433     egCore.startup.go(function() {
434         $scope.refreshTree(egCore.auth.user().ws_ou());
435     });
436 }])