Revision 48acee1e
Reprise du code de VigiGraph pour charger les groupes dynamiquement dans la recherche de VigiBoard plutôt que statiquement.
Éviter une erreur dans Firefox ("ce script ne répond plus") lorsqu'il y a beaucoup de groupes
et que mootools met trop de temps à tout traiter (cf. #408).
git-svn-id: https://vigilo-dev.si.c-s.fr/svn@5660 b22e2e97-25c9-44ff-b637-2e5ceca36478
vigiboard/controllers/root.py | ||
---|---|---|
551 | 551 |
ids = map(int, id.strip(',').split(',')) |
552 | 552 |
|
553 | 553 |
user = get_current_user() |
554 |
events = VigiboardRequest(user) |
|
554 |
events = VigiboardRequest(user, access_needed=['w'])
|
|
555 | 555 |
events.add_table(CorrEvent) |
556 | 556 |
events.add_join((Event, CorrEvent.idcause == Event.idevent)) |
557 | 557 |
events.add_join((events.items, |
... | ... | |
723 | 723 |
|
724 | 724 |
@require(access_restriction) |
725 | 725 |
@expose('json') |
726 |
def get_groups(self): |
|
727 |
hierarchy = [] |
|
728 |
user = get_current_user() |
|
729 |
groups = DBSession.query( |
|
730 |
SupItemGroup.idgroup, |
|
731 |
SupItemGroup.name, |
|
732 |
GroupHierarchy.idparent, |
|
733 |
).join( |
|
734 |
(GroupHierarchy, GroupHierarchy.idchild == \ |
|
735 |
SupItemGroup.idgroup), |
|
736 |
).filter(GroupHierarchy.hops <= 1 |
|
737 |
).order_by(GroupHierarchy.hops.asc() |
|
738 |
).order_by(SupItemGroup.name.asc()) |
|
726 |
def get_groups(self, parent_id=None): |
|
727 |
""" |
|
728 |
Affiche un étage de l'arbre de |
|
729 |
sélection des hôtes et groupes d'hôtes. |
|
730 |
|
|
731 |
@param parent_id: identifiant du groupe d'hôte parent |
|
732 |
@type parent_id: C{int} or None |
|
733 |
""" |
|
734 |
|
|
735 |
# Si l'identifiant du groupe parent n'est pas |
|
736 |
# spécifié, on retourne la liste des groupes racines, |
|
737 |
# fournie par la méthode get_root_hosts_groups. |
|
738 |
if parent_id is None: |
|
739 |
return self.get_root_host_groups() |
|
740 |
|
|
741 |
# TODO: Utiliser un schéma de validation |
|
742 |
parent_id = int(parent_id) |
|
739 | 743 |
|
744 |
# On vérifie si le groupe parent fait partie des |
|
745 |
# groupes auxquel l'utilisateur a accès, et on |
|
746 |
# retourne une liste vide dans le cas contraire |
|
740 | 747 |
is_manager = in_group('managers').is_met(request.environ) |
741 | 748 |
if not is_manager: |
742 |
user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]] |
|
743 |
groups = groups.filter(SupItemGroup.idgroup.in_(user_groups)) |
|
744 |
|
|
745 |
def find_parent(idgroup): |
|
746 |
def __find_parent(hier, idgroup): |
|
747 |
for g in hier: |
|
748 |
if g['idgroup'] == idgroup: |
|
749 |
return g['children'] |
|
750 |
for g in hier: |
|
751 |
res = __find_parent(g['children'], idgroup) |
|
752 |
if res: |
|
753 |
return res |
|
754 |
return None |
|
755 |
parent = __find_parent(hierarchy, idgroup) |
|
756 |
if parent is None: |
|
757 |
return hierarchy |
|
758 |
return parent |
|
759 |
|
|
760 |
for g in groups.all(): |
|
761 |
parent = find_parent(g.idparent) |
|
762 |
for item in hierarchy: |
|
763 |
if item['idgroup'] == g.idgroup: |
|
764 |
parent.append(item) |
|
765 |
hierarchy.remove(item) |
|
766 |
break |
|
749 |
direct_access = False |
|
750 |
user = get_current_user() |
|
751 |
user_groups = dict(user.supitemgroups()) |
|
752 |
# On regarde d'abord si le groupe fait partie de ceux |
|
753 |
# auquels l'utilisateur a explicitement accès, ou s'il |
|
754 |
# est un parent des groupes auxquels l'utilisateur a accès |
|
755 |
if parent_id in user_groups.keys(): |
|
756 |
direct_access = user_groups[parent_id] |
|
757 |
# Dans le cas contraire, on vérifie si le groupe est un |
|
758 |
# sous-groupe des groupes auxquels l'utilisateur a accès |
|
767 | 759 |
else: |
768 |
parent.append({ |
|
769 |
'idgroup': g.idgroup, |
|
770 |
'name': g.name, |
|
771 |
'children': [], |
|
772 |
}) |
|
760 |
id_list = [ug for ug in user_groups.keys() if user_groups[ug]] |
|
761 |
child_groups = DBSession.query(SupItemGroup.idgroup |
|
762 |
).distinct( |
|
763 |
).join( |
|
764 |
(GroupHierarchy, |
|
765 |
GroupHierarchy.idchild == SupItemGroup.idgroup), |
|
766 |
).filter(GroupHierarchy.idparent.in_(id_list) |
|
767 |
).filter(GroupHierarchy.hops > 0 |
|
768 |
).all() |
|
769 |
for ucg in child_groups: |
|
770 |
if ucg.idgroup == parent_id: |
|
771 |
direct_access = True |
|
772 |
break |
|
773 |
# Sinon, l'utilisateur n'a pas accès à ce groupe |
|
774 |
else: |
|
775 |
return dict(groups = [], leaves = []) |
|
776 |
|
|
777 |
# On récupère la liste des groupes dont |
|
778 |
# l'identifiant du parent est passé en paramètre |
|
779 |
db_groups = DBSession.query( |
|
780 |
SupItemGroup |
|
781 |
).join( |
|
782 |
(GroupHierarchy, GroupHierarchy.idchild == \ |
|
783 |
SupItemGroup.idgroup), |
|
784 |
).filter(GroupHierarchy.hops == 1 |
|
785 |
).filter(GroupHierarchy.idparent == parent_id |
|
786 |
).order_by(SupItemGroup.name.asc()) |
|
787 |
if not is_manager and not direct_access: |
|
788 |
id_list = [ug for ug in user_groups.keys()] |
|
789 |
db_groups = db_groups.filter( |
|
790 |
SupItemGroup.idgroup.in_(id_list)) |
|
791 |
groups = [] |
|
792 |
for group in db_groups.all(): |
|
793 |
groups.append({ |
|
794 |
'id' : group.idgroup, |
|
795 |
'name' : group.name, |
|
796 |
}) |
|
797 |
|
|
798 |
return dict(groups = groups, leaves = []) |
|
799 |
|
|
800 |
def get_root_host_groups(self): |
|
801 |
""" |
|
802 |
Retourne tous les groupes racines (c'est à dire n'ayant |
|
803 |
aucun parent) d'hôtes auquel l'utilisateur a accès. |
|
804 |
|
|
805 |
@return: Un dictionnaire contenant la liste de ces groupes. |
|
806 |
@rtype : C{dict} of C{list} of C{dict} of C{mixed} |
|
807 |
""" |
|
773 | 808 |
|
774 |
return dict(groups=hierarchy) |
|
809 |
# On récupère tous les groupes qui ont un parent. |
|
810 |
children = DBSession.query( |
|
811 |
SupItemGroup, |
|
812 |
).distinct( |
|
813 |
).join( |
|
814 |
(GroupHierarchy, GroupHierarchy.idchild == SupItemGroup.idgroup) |
|
815 |
).filter(GroupHierarchy.hops > 0) |
|
816 |
|
|
817 |
# Ensuite on les exclut de la liste des groupes, |
|
818 |
# pour ne garder que ceux qui sont au sommet de |
|
819 |
# l'arbre et qui constituent nos "root groups". |
|
820 |
root_groups = DBSession.query( |
|
821 |
SupItemGroup, |
|
822 |
).except_(children |
|
823 |
).order_by(SupItemGroup.name) |
|
824 |
|
|
825 |
# On filtre ces groupes racines afin de ne |
|
826 |
# retourner que ceux auquels l'utilisateur a accès |
|
827 |
user = get_current_user() |
|
828 |
is_manager = in_group('managers').is_met(request.environ) |
|
829 |
if not is_manager: |
|
830 |
user_groups = [ug[0] for ug in user.supitemgroups()] |
|
831 |
root_groups = root_groups.filter( |
|
832 |
SupItemGroup.idgroup.in_(user_groups)) |
|
833 |
|
|
834 |
groups = [] |
|
835 |
for group in root_groups.all(): |
|
836 |
groups.append({ |
|
837 |
'id' : group.idgroup, |
|
838 |
'name' : group.name, |
|
839 |
}) |
|
840 |
|
|
841 |
return dict(groups = groups, leaves=[]) |
|
842 |
|
|
843 |
# @require(access_restriction) |
|
844 |
# @expose('json') |
|
845 |
# def get_groups(self): |
|
846 |
# hierarchy = [] |
|
847 |
# user = get_current_user() |
|
848 |
# groups = DBSession.query( |
|
849 |
# SupItemGroup.idgroup, |
|
850 |
# SupItemGroup.name, |
|
851 |
# GroupHierarchy.idparent, |
|
852 |
# ).join( |
|
853 |
# (GroupHierarchy, GroupHierarchy.idchild == \ |
|
854 |
# SupItemGroup.idgroup), |
|
855 |
# ).filter(GroupHierarchy.hops <= 1 |
|
856 |
# ).order_by(GroupHierarchy.hops.asc() |
|
857 |
# ).order_by(SupItemGroup.name.asc()) |
|
858 |
|
|
859 |
# is_manager = in_group('managers').is_met(request.environ) |
|
860 |
# if not is_manager: |
|
861 |
# user_groups = [ug[0] for ug in user.supitemgroups() if ug[1]] |
|
862 |
# groups = groups.filter(SupItemGroup.idgroup.in_(user_groups)) |
|
863 |
|
|
864 |
# def find_parent(idgroup): |
|
865 |
# def __find_parent(hier, idgroup): |
|
866 |
# for g in hier: |
|
867 |
# if g['idgroup'] == idgroup: |
|
868 |
# return g['children'] |
|
869 |
# for g in hier: |
|
870 |
# res = __find_parent(g['children'], idgroup) |
|
871 |
# if res: |
|
872 |
# return res |
|
873 |
# return None |
|
874 |
# parent = __find_parent(hierarchy, idgroup) |
|
875 |
# if parent is None: |
|
876 |
# return hierarchy |
|
877 |
# return parent |
|
878 |
|
|
879 |
# for g in groups.all(): |
|
880 |
# parent = find_parent(g.idparent) |
|
881 |
# for item in hierarchy: |
|
882 |
# if item['idgroup'] == g.idgroup: |
|
883 |
# parent.append(item) |
|
884 |
# hierarchy.remove(item) |
|
885 |
# break |
|
886 |
# else: |
|
887 |
# parent.append({ |
|
888 |
# 'idgroup': g.idgroup, |
|
889 |
# 'name': g.name, |
|
890 |
# 'children': [], |
|
891 |
# }) |
|
892 |
|
|
893 |
# return dict(groups=hierarchy) |
|
775 | 894 |
|
776 | 895 |
def get_last_modification_timestamp(event_id_list, |
777 | 896 |
value_if_none=datetime.now()): |
vigiboard/public/js/tree.js | ||
---|---|---|
6 | 6 |
*/ |
7 | 7 |
|
8 | 8 |
/* |
9 |
* Affichage en arbre des groupes. |
|
9 |
* Affichage en arbre des groupes d'hôtes.
|
|
10 | 10 |
*/ |
11 | 11 |
var TreeGroup = new Class({ |
12 | 12 |
Implements: [Options, Events], |
... | ... | |
15 | 15 |
this.setOptions(options); |
16 | 16 |
|
17 | 17 |
/* L'objet tree se réfère à un élément div*/ |
18 |
var container = new Element('div') |
|
19 |
this.tree = new Jx.Tree({parent: container}); |
|
18 |
this.container = new Element('div') |
|
19 |
this.container.setStyle("padding", "0 10px 10px 10px"); |
|
20 |
this.tree = new Jx.Tree({parent: this.container}); |
|
20 | 21 |
|
21 | 22 |
this.dlg = new Jx.Dialog({ |
22 | 23 |
label: this.options.title, |
23 | 24 |
modal: true, |
24 |
content: container |
|
25 |
resize: true, |
|
26 |
content: this.container |
|
25 | 27 |
}); |
26 | 28 |
|
29 |
this.redraw(); |
|
30 |
}, |
|
31 |
|
|
32 |
/* Récupération des items (noeuds/feuilles) de l'arbre dépendant |
|
33 |
* du parent dont l'identifiant est passé en paramètre */ |
|
34 |
retrieve_tree_items: function(parent_node, top_node) { |
|
35 |
|
|
36 |
// Si l'identifiant est bien défini, on ajoute les |
|
37 |
// items récupérés à leur parent dans l'arbre |
|
27 | 38 |
var req = new Request.JSON({ |
28 |
method: "get", |
|
29 | 39 |
url: this.options.url, |
30 |
onSuccess: function(groups) { |
|
31 |
$each(groups.groups, function(item) { |
|
32 |
this.addItem(item, this.tree); |
|
33 |
}, this); |
|
40 |
onSuccess: function(data, xml) { |
|
41 |
if ($defined(data.groups)) { |
|
42 |
data.groups.each(function(item) { |
|
43 |
this.addNode(item, parent_node); |
|
44 |
}, this); |
|
45 |
} |
|
46 |
if ($defined(data.leaves)) { |
|
47 |
data.leaves.each(function(item) { |
|
48 |
this.addLeaf(item, parent_node); |
|
49 |
}, this); |
|
50 |
} |
|
51 |
this.fireEvent("branchloaded"); |
|
34 | 52 |
}.bind(this) |
35 | 53 |
}); |
36 |
req.send(); |
|
54 |
|
|
55 |
// Envoi de la requête |
|
56 |
if (!$chk(top_node)) |
|
57 |
req.get({parent_id: parent_node.options.data}); |
|
58 |
else |
|
59 |
req.get(); |
|
37 | 60 |
}, |
38 | 61 |
|
39 |
/* Ajout d'un element à l'arbre */ |
|
40 |
addItem: function(data, parent) { |
|
41 |
var subfolder; |
|
42 |
if (data.children.length) { |
|
43 |
subfolder = new Jx.TreeFolder({ |
|
44 |
label: data.name, |
|
45 |
data: data.idgroup |
|
46 |
}); |
|
47 |
} |
|
48 |
else { |
|
49 |
subfolder = new Jx.TreeItem({ |
|
50 |
label: data.name, |
|
51 |
data: data.idgroup |
|
52 |
}); |
|
53 |
} |
|
54 |
|
|
55 |
subfolder.addEvent("click", function() { |
|
56 |
this.fireEvent('select', [subfolder]); |
|
57 |
this.dlg.close(); |
|
62 |
/* Ajout d'un noeud à l'arbre */ |
|
63 |
addNode: function(data, parent_node) { |
|
64 |
var node = new Jx.TreeFolder({ |
|
65 |
label: data.name, |
|
66 |
data: data.id |
|
67 |
}); |
|
68 |
|
|
69 |
node.addEvent("disclosed", function(node) { |
|
70 |
this.fireEvent("nodedisclosed", node); |
|
71 |
if (!node.options.open || node.nodes.length > 0) |
|
72 |
return; |
|
73 |
this.retrieve_tree_items(node); |
|
74 |
}.bind(this)); |
|
75 |
|
|
76 |
node.addEvent("click", function() { |
|
77 |
this[0].fireEvent('select', this[1]); |
|
78 |
this[0].dlg.close(); |
|
58 | 79 |
return false; |
80 |
}.bind([this, node])); |
|
81 |
|
|
82 |
parent_node.append(node); |
|
83 |
}, |
|
84 |
|
|
85 |
/* Ajout d'une feuille à l'arbre */ |
|
86 |
addLeaf: function(data, parent_node) { |
|
87 |
var leaf = new Jx.TreeItem({ |
|
88 |
label: data.name, |
|
89 |
data: data.id |
|
90 |
}); |
|
91 |
|
|
92 |
leaf.addEvent("click", function() { |
|
93 |
this.fireEvent('select', [leaf]); |
|
94 |
this.dlg.close(); |
|
59 | 95 |
}.bind(this)); |
60 |
parent.append(subfolder); |
|
61 | 96 |
|
62 |
$each(data.children, function(item) { |
|
63 |
this.addItem(item, subfolder); |
|
64 |
}, this); |
|
97 |
parent_node.append(leaf); |
|
65 | 98 |
}, |
66 | 99 |
|
67 | 100 |
selectGroup: function() { |
68 | 101 |
this.dlg.open(); |
102 |
}, |
|
103 |
|
|
104 |
redraw: function() { |
|
105 |
this.tree.clear(); |
|
106 |
this.retrieve_tree_items(this.tree, true); |
|
69 | 107 |
} |
70 | 108 |
}); |
Also available in: Unified diff