From 0f43da13c5c602e0bf62b9a3154db1f5f59fbc53 Mon Sep 17 00:00:00 2001 From: Kyle Huckins Date: Thu, 15 Mar 2018 18:54:13 +0000 Subject: [PATCH] lp1744756 Profile Tree Display Entry Admin UI - Flesh out permission.group_tree_display_entries table. - Create pgtde IDL class corresponding to new permission.group_tree_display_entries table. - Admin UI for Permission Group Tree Entries capable of viewing, adding, removing, or changing position of entries within tree based on OU. - Save functionality to persist any changes made. - Persist changes in positions of permission group display entries in Admin UI with the Profile Selector in the patron edit interface. - Make profile selector use original functionality if there are no display entries. Signed-off-by: Kyle Huckins Signed-off-by: Bill Erickson Signed-off-by: Kathy Lussier --- Open-ILS/examples/fm_IDL.xml | 25 + .../src/sql/Pg/006.schema.permissions.sql | 14 + .../XXXX.schema.perm-group-display.sql | 19 + .../staff/admin/local/permission/index.tt2 | 26 + .../permission/t_grp_tree_display_entry.tt2 | 60 +++ .../local/permission/t_pgtde_add_dialog.tt2 | 36 ++ .../templates/staff/admin/local/t_splash.tt2 | 1 + .../templates/staff/circ/patron/t_edit.tt2 | 10 +- .../staff/admin/local/permission/app.js | 443 ++++++++++++++++++ .../js/ui/default/staff/circ/patron/regctl.js | 86 +++- 10 files changed, 717 insertions(+), 3 deletions(-) create mode 100644 Open-ILS/src/sql/Pg/upgrade/XXXX.schema.perm-group-display.sql create mode 100644 Open-ILS/src/templates/staff/admin/local/permission/index.tt2 create mode 100644 Open-ILS/src/templates/staff/admin/local/permission/t_grp_tree_display_entry.tt2 create mode 100644 Open-ILS/src/templates/staff/admin/local/permission/t_pgtde_add_dialog.tt2 create mode 100644 Open-ILS/web/js/ui/default/staff/admin/local/permission/app.js diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml index 2a7005f2f8..b12a0438f9 100644 --- a/Open-ILS/examples/fm_IDL.xml +++ b/Open-ILS/examples/fm_IDL.xml @@ -7644,6 +7644,31 @@ SELECT usr, + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Open-ILS/src/sql/Pg/006.schema.permissions.sql b/Open-ILS/src/sql/Pg/006.schema.permissions.sql index df154fbf6c..3e1bbf2af6 100644 --- a/Open-ILS/src/sql/Pg/006.schema.permissions.sql +++ b/Open-ILS/src/sql/Pg/006.schema.permissions.sql @@ -617,6 +617,20 @@ RETURNS SETOF INTEGER AS $$ SELECT DISTINCT * FROM permission.usr_has_perm_at_all_nd( $1, $2 ); $$ LANGUAGE 'sql' ROWS 1; +CREATE TABLE permission.grp_tree_display_entry ( + id SERIAL PRIMARY KEY, + position INTEGER NOT NULL, + org INTEGER NOT NULL REFERENCES actor.org_unit (id) + DEFERRABLE INITIALLY DEFERRED, + grp INTEGER NOT NULL REFERENCES permission.grp_tree (id) + DEFERRABLE INITIALLY DEFERRED, + disabled BOOLEAN NOT NULL DEFAULT FALSE, + CONSTRAINT pgtde_once_per_org UNIQUE (org, grp) +); + +ALTER TABLE permission.grp_tree_display_entry + ADD COLUMN parent integer REFERENCES permission.grp_tree_display_entry (id) + DEFERRABLE INITIALLY DEFERRED; COMMIT; diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.perm-group-display.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.perm-group-display.sql new file mode 100644 index 0000000000..2cbbd1f227 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.perm-group-display.sql @@ -0,0 +1,19 @@ +BEGIN; +SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version); + +CREATE TABLE permission.grp_tree_display_entry ( + id SERIAL PRIMARY KEY, + position INTEGER NOT NULL, + org INTEGER NOT NULL REFERENCES actor.org_unit (id) + DEFERRABLE INITIALLY DEFERRED, + grp INTEGER NOT NULL REFERENCES permission.grp_tree (id) + DEFERRABLE INITIALLY DEFERRED, + disabled BOOLEAN NOT NULL DEFAULT FALSE, + CONSTRAINT pgtde_once_per_org UNIQUE (org, grp) +); + +ALTER TABLE permission.grp_tree_display_entry + ADD COLUMN parent integer REFERENCES permission.grp_tree_display_entry (id) + DEFERRABLE INITIALLY DEFERRED; + +COMMIT; \ No newline at end of file diff --git a/Open-ILS/src/templates/staff/admin/local/permission/index.tt2 b/Open-ILS/src/templates/staff/admin/local/permission/index.tt2 new file mode 100644 index 0000000000..6b63ed5f19 --- /dev/null +++ b/Open-ILS/src/templates/staff/admin/local/permission/index.tt2 @@ -0,0 +1,26 @@ +[% + WRAPPER "staff/base.tt2"; + ctx.page_title = l("Permission Groups"); + ctx.page_app = "egAdminPermGrpTreeApp"; +%] + +[% BLOCK APP_JS %] + + + + +[% END %] + +
+ +[% END %] \ No newline at end of file diff --git a/Open-ILS/src/templates/staff/admin/local/permission/t_grp_tree_display_entry.tt2 b/Open-ILS/src/templates/staff/admin/local/permission/t_grp_tree_display_entry.tt2 new file mode 100644 index 0000000000..2436f18c72 --- /dev/null +++ b/Open-ILS/src/templates/staff/admin/local/permission/t_grp_tree_display_entry.tt2 @@ -0,0 +1,60 @@ +
+
+ [% l('Permission Group Tree Entries') %] +
+
+ +
+
+
+
+ + +
+
+
+ + + + + +
+
+ +
+
+ + {{node.grp().name()}} + +
+
+
[% l('No Org Unit Selected') %]
+
+
+
\ No newline at end of file diff --git a/Open-ILS/src/templates/staff/admin/local/permission/t_pgtde_add_dialog.tt2 b/Open-ILS/src/templates/staff/admin/local/permission/t_pgtde_add_dialog.tt2 new file mode 100644 index 0000000000..ad30169c6a --- /dev/null +++ b/Open-ILS/src/templates/staff/admin/local/permission/t_pgtde_add_dialog.tt2 @@ -0,0 +1,36 @@ + + + \ No newline at end of file diff --git a/Open-ILS/src/templates/staff/admin/local/t_splash.tt2 b/Open-ILS/src/templates/staff/admin/local/t_splash.tt2 index 151f2bb414..90ec95af66 100644 --- a/Open-ILS/src/templates/staff/admin/local/t_splash.tt2 +++ b/Open-ILS/src/templates/staff/admin/local/t_splash.tt2 @@ -30,6 +30,7 @@ ,[ l('Non-Cataloged Types Editor'), "./admin/local/config/non_cat_types" ] ,[ l('Notifications / Action Triggers'), "./admin/local/action_trigger/event_definition" ] ,[ l('Patrons with Negative Balances'), "./admin/local/circ/neg_balance_users" ] + ,[ l('Permission Tree Display Entries'), "./admin/local/permission/grp_tree_display_entry" ] ,[ l('Search Filter Groups'), "./admin/local/actor/search_filter_group" ] ,[ l('Standing Penalties'), "./admin/local/config/standing_penalty" ] ,[ l('Statistical Categories Editor'), "./admin/local/asset/stat_cat_editor" ] diff --git a/Open-ILS/src/templates/staff/circ/patron/t_edit.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_edit.tt2 index 4dff9ce57d..85e5bdb44f 100644 --- a/Open-ILS/src/templates/staff/circ/patron/t_edit.tt2 +++ b/Open-ILS/src/templates/staff/circ/patron/t_edit.tt2 @@ -458,8 +458,14 @@ within the "form" by name for validation.
    -
  • +
  • + {{entry.grp().name()}} +
  • +
  • {{grp.name()}} diff --git a/Open-ILS/web/js/ui/default/staff/admin/local/permission/app.js b/Open-ILS/web/js/ui/default/staff/admin/local/permission/app.js new file mode 100644 index 0000000000..8c5d73f8ca --- /dev/null +++ b/Open-ILS/web/js/ui/default/staff/admin/local/permission/app.js @@ -0,0 +1,443 @@ +angular.module('egAdminPermGrpTreeApp', + ['ngRoute','ui.bootstrap','egCoreMod','egUiMod','treeControl']) + +.config(function($routeProvider, $locationProvider, $compileProvider) { + $locationProvider.html5Mode(true); + $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); + + var resolver = {delay : + ['egStartup', function(egStartup) {return egStartup.go()}]} + + $routeProvider.when('/admin/local/permission/grp_tree_display_entry', { + templateUrl : './admin/local/permission/t_grp_tree_display_entry', + controller : 'PermGrpTreeCtrl', + resolve : resolver + }); + + $routeProvider.otherwise({redirectTo : '/admin/local/permission/grp_tree'}); +}) + +.factory('egPermGrpTreeSvc', + ['$q','egCore', function($q , egCore) { + var service = { + pgtde_array: [], + display_entries: [], + disabled_entries: [], + profiles: [], + edit_profiles: [] + }; + + // determine which user groups our user is not allowed to modify + service.set_edit_profiles = function() { + var all_app_perms = []; + var failed_perms = []; + + // extract the application permissions + angular.forEach(service.profiles, function(grp) { + if (grp.application_perm()) + all_app_perms.push(grp.application_perm()); + }); + + // fill in service.edit_profiles by inspecting failed_perms + function traverse_grp_tree(grp, failed) { + failed = failed || + failed_perms.indexOf(grp.application_perm()) > -1; + + if (!failed) service.edit_profiles.push(grp); + + angular.forEach( + service.profiles.filter( // children of grp + function(p) { return p.parent() == grp.id() }), + function(child) {traverse_grp_tree(child, failed)} + ); + } + + return egCore.perm.hasPermAt(all_app_perms, true).then( + function(perm_orgs) { + angular.forEach(all_app_perms, function(p) { + if (perm_orgs[p].length == 0) + failed_perms.push(p); + }); + + traverse_grp_tree(egCore.env.pgt.tree); + } + ); + } + + service.get_perm_groups = function() { + if (egCore.env.pgt) { + service.profiles = egCore.env.pgt.list; + return service.set_edit_profiles(); + } else { + return egCore.pcrud.search('pgt', {parent : null}, + {flesh : -1, flesh_fields : {pgt : ['children']}} + ).then( + function(tree) { + egCore.env.absorbTree(tree, 'pgt') + service.profiles = egCore.env.pgt.list; + return service.set_edit_profiles(); + } + ); + } + } + + service.fetchDisplayEntries = function(ou_id) { + service.edit_profiles = []; + service.get_perm_groups(); + return egCore.pcrud.search('pgtde', + {org : egCore.org.ancestors(ou_id, true)}, + { flesh : 1, + flesh_fields : { + pgtde: ['grp', 'org'] + }, + order_by: {pgtde : 'id'} + }, + {atomic: true} + ).then(function(entries) { + service.pgtde_array = []; + service.disabled_entries = []; + angular.forEach(entries, function(entry) { + if (entry.disabled() == 'f') { + entry.disabled(false); + service.pgtde_array.push(entry); + } + if (entry.disabled() == 't') { + entry.disabled(true); + service.disabled_entries.push(entry); + } + }); + }); + } + + service.organizeDisplayEntries = function(selectedOrg) { + service.display_entries = []; + + angular.forEach(service.pgtde_array, function(pgtde) { + if (pgtde.org().id() == selectedOrg) { + if (!pgtde.child_entries) pgtde.child_entries = []; + var isChild = false; + angular.forEach(service.display_entries, function(entry) { + if (pgtde.parent() && pgtde.parent() == entry.id()) { + entry.child_entries.push(pgtde); + isChild = true; + return; + } else { + if (service.iterateChildEntries(pgtde, entry)) { + isChild = true; + return; + } + } + }); + if (!pgtde.parent() || !isChild) { + service.display_entries.push(pgtde); + } + } + }); + } + + service.iterateChildEntries = function(pgtde, entry) { + if (entry.child_entries.length) { + return angular.forEach(entry.child_entries, function(child) { + if (pgtde.parent() == child.id()) { + child.child_entries.push(pgtde); + return true; + } else { + return service.iterateChildEntries(pgtde, child); + } + }); + } + } + + service.updateDisplayEntries = function(tree, ou_id) { + return egCore.pcrud.search('pgtde', + {org : ou_id}, + { flesh : 1, + flesh_fields : { + pgtde: ['grp', 'org'] + }, + order_by: {pgtde : 'id'} + }, + {atomic: true} + ).then(function(entries) { + return egCore.pcrud.update(tree).then(function(res) { + return res; + }); + }); + } + + service.removeDisplayEntries = function(entries) { + return egCore.pcrud.remove(entries).then(function(res) { + return res; + }); + } + + service.addDisplayEntries = function(entries) { + return egCore.pcrud.create(entries).then(function(res) { + return res; + }); + } + + service.findEntry = function(id, entries) { + var match; + angular.forEach(entries, function(entry) { + if (!match) { + if (!entry.child_entries) entry.child_entries = []; + if (id == entry.id()) { + match = entry; + } else if (entry.child_entries.length) { + match = service.findEntry(id, entry.child_entries); + } + } + }); + + return match; + } + + return service; +}]) + +.controller('PermGrpTreeCtrl', + ['$scope','$q','$timeout','$location','$uibModal','egCore','egPermGrpTreeSvc', 'ngToast', 'egProgressDialog', +function($scope , $q , $timeout , $location , $uibModal , egCore , egPermGrpTreeSvc, ngToast, egProgressDialog) { + $scope.perm_tree = [{ + grp: function() { + return { + name: function() {return egCore.strings.ROOT_NODE_NAME;} + } + }, + child_entries: [], + permanent: 'true' + }]; + $scope.display_entries = []; + $scope.new_entries = []; + $scope.tree_options = {nodeChildren: 'child_entries'}; + $scope.selected_entry; + $scope.expanded_nodes = []; + $scope.orderby = ['position()','grp().name()']; + + if (!$scope.selectedOrg) + $scope.selectedOrg = egCore.org.get(egCore.auth.user().ws_ou()); + + $scope.updateSelection = function(node, selected) { + $scope.selected_entry = node; + if (!selected) $scope.selected_entry = null; + } + + $scope.setPosition = function(node, direction) { + var newPos = node.position(); + var siblings; + if (node.parent()) { + siblings = egPermGrpTreeSvc.findEntry(node.parent(), $scope.perm_tree[0].child_entries).child_entries; + } else { + siblings = $scope.perm_tree[0].child_entries; + } + if (direction == 'up' && newPos < siblings.length) newPos++; + if (direction == 'down' && newPos > 1) newPos--; + + angular.forEach(siblings, function(entry) { + if (entry.position() == newPos) entry.position(node.position()); + angular.forEach($scope.display_entries, function(display_entry) { + if (display_entry.id() == entry.id()) { + if (display_entry.position() == newPos) { + display_entry.position(node.position); + }; + } + }); + }); + + angular.forEach($scope.display_entries, function(display_entry) { + if (display_entry.id() == node.id()) { + display_entry.position(newPos); + } + }); + + node.position(newPos); + } + + $scope.addChildEntry = function(node) { + + $scope.openAddDialog(node, $scope.disabled_entries, $scope.edit_profiles, $scope.display_entries, $scope.selectedOrg) + .then(function(res) { + if (res) { + + var siblings = [] + var new_entry = new egCore.idl.pgtde(); + new_entry.org($scope.selectedOrg.id()); + new_entry.grp(res.selected_grp); + new_entry.position(1); + new_entry.child_entries = []; + var is_expanded; + if (res.selected_parent) { + new_entry.parent(res.selected_parent); + angular.forEach($scope.expanded_nodes, function(expanded_node) { + if (expanded_node == res.selected_parent) is_expanded = true; + }); + if (!is_expanded) $scope.expanded_nodes.push(res.selected_parent); + } else { + angular.forEach($scope.expanded_nodes, function(expanded_node) { + if (expanded_node == $scope.perm_tree[0]) is_expanded = true; + }); + if (!is_expanded) $scope.expanded_nodes.push($scope.perm_tree[0]); + } + + $scope.display_entries.push(new_entry); + egPermGrpTreeSvc.addDisplayEntries([new_entry]).then(function(addRes) { + if (addRes) { + if (res.is_root || !res.selected_parent) { + angular.forEach($scope.perm_tree[0].child_entries, function(entry) { + var newPos = entry.position(); + newPos++; + entry.position(newPos); + siblings.push(entry); + }); + } else { + var parent = egPermGrpTreeSvc.findEntry(res.selected_parent.id(), $scope.perm_tree[0].child_entries); + angular.forEach(parent.child_entries, function(entry) { + var newPos = entry.position(); + newPos++; + entry.position(newPos); + siblings.push(entry); + }); + } + + egPermGrpTreeSvc.updateDisplayEntries(siblings).then(function(updateRes) { + ngToast.create(egCore.strings.ADD_SUCCESS); + $scope.refreshTree($scope.selectedOrg, $scope.selected_entry); + }); + } else { + ngToast.create(egCore.strings.ADD_FAILURE); + } + }); + } + }); + } + + $scope.openAddDialog = function(node, disabled_entries, edit_profiles, display_entries, selected_org) { + + return $uibModal.open({ + templateUrl : './admin/local/permission/t_pgtde_add_dialog', + backdrop: 'static', + controller : [ + '$scope','$uibModalInstance', + function($scope , $uibModalInstance) { + var getIsRoot = function() { + if (!node || node.permanent) return true; + return false; + } + + var getSelectedParent = function() { + if (!node || node.permanent) return $scope.perm_tree; + return node; + } + + var available_profiles = []; + angular.forEach(edit_profiles, function(grp) { + grp._filter_grp = false; + angular.forEach(display_entries, function(entry) { + if (entry.org().id() == selected_org.id()) { + if (entry.grp().id() == grp.id()) grp._filter_grp = true; + } + }); + if (!grp._filter_grp) available_profiles.push(grp); + }); + + $scope.context = { + is_root : getIsRoot(), + selected_parent : getSelectedParent(), + edit_profiles : available_profiles, + display_entries : display_entries, + selected_org : selected_org + } + + $scope.context.selected_grp = $scope.context.edit_profiles[0]; + + $scope.ok = function() { + $uibModalInstance.close($scope.context); + } + + $scope.cancel = function() { + $uibModalInstance.dismiss(); + } + } + ] + }).result; + } + + var iteratePermTree = function(arr1, arr2) { + angular.forEach(arr1, function(entry) { + arr2.push(entry); + if (entry.child_entries) iteratePermTree(entry.child_entries, arr2); + }); + } + + $scope.removeEntry = function(node) { + $scope.disabled_entries.push(node); + iteratePermTree(node.child_entries, $scope.disabled_entries); + + var siblings; + if (node.parent()) { + siblings = egPermGrpTreeSvc.findEntry(node.parent(), $scope.perm_tree[0].child_entries).child_entries; + } else { + siblings = $scope.perm_tree[0].child_entries; + } + angular.forEach(siblings, function(sibling) { + var newPos = sibling.position(); + if (node.position() < sibling.position()) { + newPos--; + } + sibling.position(newPos); + }); + + $scope.selected_entry = null; + + egPermGrpTreeSvc.removeDisplayEntries($scope.disabled_entries).then(function(res) { + if (res) { + ngToast.create(egCore.strings.REMOVE_SUCCESS); + $scope.refreshTree($scope.selectedOrg); + } else { + ngToast.create(egCore.strings.REMOVE_FAILURE); + } + }) + } + + var getDisplayEntries = function() { + $scope.edit_profiles = egPermGrpTreeSvc.edit_profiles; + egPermGrpTreeSvc.organizeDisplayEntries($scope.selectedOrg.id()); + $scope.perm_tree[0].child_entries = egPermGrpTreeSvc.display_entries; + $scope.display_entries = egPermGrpTreeSvc.pgtde_array; + $scope.new_entries = []; + $scope.disabled_entries = []; + $scope.selected_entry = $scope.perm_tree[0]; + if (!$scope.expanded_nodes.length) iteratePermTree($scope.perm_tree, $scope.expanded_nodes); + } + + $scope.saveEntries = function() { + egProgressDialog.open(); + + // Save Remaining Display Entries + egPermGrpTreeSvc.updateDisplayEntries($scope.display_entries, $scope.selectedOrg.id()) + .then(function(res) { + if (res) { + ngToast.create(egCore.strings.UPDATE_SUCCESS); + $scope.refreshTree($scope.selectedOrg, $scope.selected_entry); + } else { + ngToast.create(egCore.strings.UPDATE_FAILURE); + } + }).finally(egProgressDialog.close); + } + + $scope.org_changed = function(org) { + $scope.refreshTree(org.id()); + } + + $scope.refreshTree = function(ou_id, node) { + egPermGrpTreeSvc.fetchDisplayEntries(ou_id).then(function() { + getDisplayEntries(); + if (node) $scope.selected_entry = node; + }); + } + + egCore.startup.go(function() { + $scope.refreshTree(egCore.auth.user().ws_ou()); + }); +}]) \ No newline at end of file diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/regctl.js b/Open-ILS/web/js/ui/default/staff/circ/patron/regctl.js index d11c7408b3..d4b9728da7 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/patron/regctl.js +++ b/Open-ILS/web/js/ui/default/staff/circ/patron/regctl.js @@ -2,12 +2,14 @@ angular.module('egCoreMod') // toss tihs onto egCoreMod since the page app may vary -.factory('patronRegSvc', ['$q', 'egCore', 'egLovefield', function($q, egCore, egLovefield) { +.factory('patronRegSvc', ['$q', '$filter', 'egCore', 'egLovefield', function($q, $filter, egCore, egLovefield) { var service = { field_doc : {}, // config.idl_field_doc profiles : [], // permission groups + profile_entries : [], // permission gorup display entries edit_profiles : [], // perm groups we can modify + edit_profile_entries : [], // perm group display entries we can modify sms_carriers : [], user_settings : {}, // applied user settings user_setting_types : {}, // config.usr_setting_type @@ -38,6 +40,7 @@ angular.module('egCoreMod') common_data = [ service.get_field_doc(), service.get_perm_groups(), + service.get_perm_group_entries(), service.get_ident_types(), service.get_org_settings(), service.get_stat_cats(), @@ -200,6 +203,44 @@ angular.module('egCoreMod') ); } + service.set_edit_profile_entries = function() { + var all_app_perms = []; + var failed_perms = []; + + // extract the application permissions + angular.forEach(service.profile_entries, function(entry) { + if (entry.grp().application_perm()) + all_app_perms.push(entry.grp().application_perm()); + }); + + // fill in service.edit_profiles by inspecting failed_perms + function traverse_grp_tree(entry, failed) { + failed = failed || + failed_perms.indexOf(entry.grp().application_perm()) > -1; + + if (!failed) service.edit_profile_entries.push(entry); + + angular.forEach( + service.profile_entries.filter( // children of grp + function(p) { return p.parent() == entry.id() }), + function(child) {traverse_grp_tree(child, failed)} + ); + } + + return egCore.perm.hasPermAt(all_app_perms, true).then( + function(perm_orgs) { + angular.forEach(all_app_perms, function(p) { + if (perm_orgs[p].length == 0) + failed_perms.push(p); + }); + + angular.forEach(egCore.env.pgtde.tree, function(tree) { + traverse_grp_tree(tree); + }); + } + ); + } + // resolves to a hash of perm-name => boolean value indicating // wether the user has the permission at org_id. service.has_perms_for_org = function(org_id) { @@ -442,6 +483,41 @@ angular.module('egCoreMod') } } + service.get_perm_group_entries = function() { + if (egCore.env.pgtde) { + service.profile_entries = egCore.env.pgtde.list; + return service.set_edit_profile_entries(); + } else { + return egCore.pcrud.search('pgtde', {org: egCore.auth.user().ws_ou(), parent: null}, + {flesh : -1, flesh_fields : {pgtde : ['grp', 'children']}}, {atomic : true} + ).then(function(treeArray) { + function compare(a,b) { + if (a.position() > b.position()) + return -1; + if (a.position() < b.position()) + return 1; + return 0; + } + + var list = []; + function squash(node) { + if (node.disabled() == 'f') { + node.children().sort(compare) + list.push(node); + angular.forEach(node.children(), squash); + } + } + + angular.forEach(treeArray, squash); + var blob = egCore.env.absorbList(list, 'pgtde'); + blob.tree = treeArray; + + service.profile_entries = egCore.env.pgtde.list; + return service.set_edit_profile_entries(); + }); + } + } + service.get_field_doc = function() { var to_cache = []; return egCore.pcrud.search('fdoc', { @@ -1227,6 +1303,7 @@ function($scope , $routeParams , $q , $uibModal , $window , egCore , $scope.patron = patron; $scope.field_doc = prs.field_doc; $scope.edit_profiles = prs.edit_profiles; + $scope.edit_profile_entries = prs.edit_profile_entries; $scope.ident_types = prs.ident_types; $scope.net_access_levels = prs.net_access_levels; $scope.user_setting_types = prs.user_setting_types; @@ -1298,6 +1375,13 @@ function($scope , $routeParams , $q , $uibModal , $window , egCore , return d; } + // returns the tree depth of the selected profile group tree node. + $scope.pgtde_depth = function(entry) { + var d = 0; + while (entry = egCore.env.pgtde.map[entry.parent()]) d++; + return d; + } + // IDL fields used for labels in the UI. $scope.idl_fields = { au : egCore.idl.classes.au.field_map, -- 2.43.2