Revision 8f6567c2
Détection des changements dans la partie "fragment" de l'URL (pour les bookmarks) et mise à jour des graphes en conséquence (#425).
Lorsqu'il n'y a qu'un seul graphe affiché, pré-sélection de l'hôte et du graphe dans la barre d'outil de VigiGraph (demandé par un client).
git-svn-id: https://vigilo-dev.si.c-s.fr/svn@6102 b22e2e97-25c9-44ff-b637-2e5ceca36478
vigigraph/controllers/rpc.py | ||
---|---|---|
697 | 697 |
return {"mtime": None} |
698 | 698 |
mtime = change.last_modified.replace(microsecond=0) |
699 | 699 |
return {"mtime": mtime} |
700 |
|
|
701 |
@expose('json') |
|
702 |
def selectHostAndGraph(self, host, graph): |
|
703 |
# @TODO: vérifier les permissions |
|
704 |
ids = DBSession.query( |
|
705 |
Host.idhost, Graph.idgraph |
|
706 |
).join( |
|
707 |
(PerfDataSource, PerfDataSource.idhost == Host.idhost), |
|
708 |
(GRAPH_PERFDATASOURCE_TABLE, \ |
|
709 |
GRAPH_PERFDATASOURCE_TABLE.c.idperfdatasource == \ |
|
710 |
PerfDataSource.idperfdatasource), |
|
711 |
(Graph, Graph.idgraph == \ |
|
712 |
GRAPH_PERFDATASOURCE_TABLE.c.idgraph), |
|
713 |
).filter(Graph.name == unicode(graph) |
|
714 |
).filter(Host.name == unicode(host) |
|
715 |
).first() |
|
716 |
|
|
717 |
return { |
|
718 |
'idhost': ids and ids.idhost or None, |
|
719 |
'idgraph': ids and ids.idgraph or None, |
|
720 |
} |
vigigraph/public/js/graph.js | ||
---|---|---|
1 |
var refresh_delay = 30; |
|
2 |
var graphs = []; |
|
3 |
|
|
4 |
var old_fragment = ''; |
|
5 |
var skip_detection = 0; |
|
6 |
|
|
7 |
|
|
1 | 8 |
var Graph = new Class({ |
2 | 9 |
Implements: [Events, Options], |
3 | 10 |
|
... | ... | |
16 | 23 |
this.host = host; |
17 | 24 |
this.graph = graph; |
18 | 25 |
this.refreshTimer = null; |
26 |
this.destroyed = false; |
|
19 | 27 |
|
20 | 28 |
new Request.JSON({ |
21 | 29 |
url: app_path + 'rpc/startTime', |
... | ... | |
98 | 106 |
this.refreshTimer = |
99 | 107 |
this.updateGraph.periodical(delay * 1000, this); |
100 | 108 |
this.options.autoRefresh = 1; |
101 |
this.updateURI();
|
|
109 |
window.updateURI();
|
|
102 | 110 |
}.bind(this), |
103 | 111 |
onUp: function() { |
104 | 112 |
clearInterval(this.refreshTimer); |
105 | 113 |
this.options.autoRefresh = 0; |
106 |
this.updateURI();
|
|
114 |
window.updateURI();
|
|
107 | 115 |
}.bind(this) |
108 | 116 |
}); |
109 | 117 |
|
... | ... | |
192 | 200 |
toolbars: [toolbar] |
193 | 201 |
}); |
194 | 202 |
|
195 |
function removeDialog() { |
|
196 |
window.graphs.erase(this); |
|
197 |
this.updateURI(); |
|
198 |
} |
|
199 |
|
|
200 | 203 |
this.updateGraph(); |
201 | 204 |
this.graph_window.open(); |
202 |
window.graphs.push(this); |
|
203 | 205 |
|
204 | 206 |
this.refresh_button.setActive(parseInt(this.options.autoRefresh)); |
205 | 207 |
|
206 |
this.graph_window.addEvent('close', removeDialog.bind(this)); |
|
208 |
var onClose = function () { |
|
209 |
if (this.destroyed) return; |
|
210 |
this.destroyed = true; |
|
211 |
this.graph_window.domObj.dispose(); |
|
212 |
window.graphs.erase(this); |
|
213 |
window.updateURI(); |
|
214 |
}; |
|
215 |
|
|
216 |
this.graph_window.addEvent('close', onClose.bind(this)); |
|
207 | 217 |
// sizeChange est déclenché à la fois après un redimensionnement |
208 | 218 |
// et après un déplacement. Ce cas est mal documenté dans JxLib. |
209 | 219 |
this.graph_window.addEvent('sizeChange', this.dialogMoved.bind(this)); |
... | ... | |
211 | 221 |
// Simule un déplacement de la fenêtre, |
212 | 222 |
// pour mettre à jour les coordonnées. |
213 | 223 |
this.dialogMoved(); |
224 |
window.graphs.push(this); |
|
225 |
return this; |
|
226 |
}, |
|
227 |
|
|
228 |
destroy: function () { |
|
229 |
this.graph_window.close(); |
|
214 | 230 |
}, |
215 | 231 |
|
216 | 232 |
dialogMoved: function () { |
217 | 233 |
// Repris de l'API interne de JxLib (création du Drag). |
218 | 234 |
this.options.left = parseInt(this.graph_window.domObj.style.left, 10); |
219 | 235 |
this.options.top = parseInt(this.graph_window.domObj.style.top, 10); |
220 |
this.updateURI();
|
|
236 |
window.updateURI();
|
|
221 | 237 |
}, |
222 | 238 |
|
223 | 239 |
updateZoom: function (factor) { |
... | ... | |
230 | 246 |
this.updateGraph(); |
231 | 247 |
}, |
232 | 248 |
|
233 |
updateURI: function () { |
|
234 |
var graphs = []; |
|
235 |
var uri = new URI(); |
|
236 |
uri.set('fragment', ''); |
|
237 |
|
|
238 |
window.graphs.each(function (graph) { |
|
239 |
var props = new Hash(graph.options); |
|
240 |
props.extend({host: graph.host, graph: graph.graph}); |
|
241 |
this.push(props.toQueryString()); |
|
242 |
}, graphs); |
|
243 |
|
|
244 |
uri.setData({'graphs': graphs, safety: 1}, false, 'fragment'); |
|
245 |
uri.go(); |
|
246 |
}, |
|
247 |
|
|
248 | 249 |
getStartTime: function () { |
249 | 250 |
var start = this.options.start; |
250 | 251 |
if (start == null) |
... | ... | |
342 | 343 |
} |
343 | 344 |
}); |
344 | 345 |
|
345 |
var refresh_delay = 30; |
|
346 |
var graphs = []; |
|
347 |
window.addEvent('load', function () { |
|
348 |
new Request.JSON({ |
|
349 |
url: app_path + 'rpc/tempoDelayRefresh', |
|
350 |
onSuccess: function (data) { |
|
351 |
window.refresh_delay = data.delay; |
|
352 |
} |
|
353 |
}).get(); |
|
346 |
var updateURI = function () { |
|
347 |
var graphs_uri = []; |
|
348 |
var uri = new URI(); |
|
354 | 349 |
|
350 |
// Section critique. |
|
351 |
window.skip_detection++; |
|
352 |
uri.set('fragment', ''); |
|
353 |
|
|
354 |
window.graphs.each(function (graph) { |
|
355 |
var props = new Hash(graph.options); |
|
356 |
props.extend({host: graph.host, graph: graph.graph}); |
|
357 |
this.push(props.toQueryString()); |
|
358 |
}, graphs_uri); |
|
359 |
|
|
360 |
uri.setData({'graphs': graphs_uri, safety: 1}, false, 'fragment'); |
|
361 |
uri.go(); |
|
362 |
window.old_fragment = uri.toString(); |
|
363 |
|
|
364 |
// Fin de section critique. |
|
365 |
window.skip_detection--; |
|
366 |
}; |
|
367 |
|
|
368 |
var update_visible_graphs = function (new_fragment) { |
|
355 | 369 |
// On réouvre les graphes précédemment chargés. |
356 |
var graphs = []; |
|
357 |
var uri = new URI(); |
|
358 |
var qs = new Hash(uri.get('fragment').parseQueryString()); |
|
370 |
var new_graphs = []; |
|
371 |
var qs = new Hash(new_fragment.get('fragment').parseQueryString()); |
|
359 | 372 |
if (qs.has('graphs')) { |
360 |
graphs = (new Hash(qs.get('graphs'))).getValues(); |
|
373 |
new_graphs = (new Hash(qs.get('graphs'))).getValues();
|
|
361 | 374 |
} |
362 | 375 |
|
363 |
graphs.each(function (graph) { |
|
376 |
// Section critique. |
|
377 |
window.skip_detection++; |
|
378 |
|
|
379 |
var prev_graphs = window.graphs; |
|
380 |
window.graphs = []; |
|
381 |
prev_graphs.each(function (graph) { graph.destroy(); }); |
|
382 |
|
|
383 |
new_graphs.each(function (graph) { |
|
364 | 384 |
var uri = new URI('?' + graph); |
365 | 385 |
var qs = new Hash(uri.getData()); |
366 | 386 |
if (qs.has('host') && qs.has('graph')) { |
... | ... | |
387 | 407 |
} |
388 | 408 |
}); |
389 | 409 |
|
390 |
// Nécessaire car le constructeur de Graph ajoute les graphes à l'URI. |
|
391 |
// On restaure donc l'ancienne URI ici, pour éviter les doublons. |
|
392 |
if (graphs.length) |
|
393 |
uri.go(); |
|
410 |
window.updateURI(); |
|
411 |
|
|
412 |
// Fin de section critique. |
|
413 |
window.skip_detection--; |
|
414 |
|
|
415 |
if (window.graphs.length == 1) { |
|
416 |
new Request.JSON({ |
|
417 |
url: app_path + 'rpc/selectHostAndGraph', |
|
418 |
onSuccess: function (results) { |
|
419 |
window.toolbar.host_picker.setItem(results.idhost, this[0]); |
|
420 |
window.toolbar.graph_picker.idselection = results.idgraph; |
|
421 |
window.toolbar.graph_picker.setLabel(this[1]); |
|
422 |
}.bind([ |
|
423 |
window.graphs[0].host, |
|
424 |
window.graphs[0].graph |
|
425 |
]) |
|
426 |
}).get({ |
|
427 |
host: window.graphs[0].host, |
|
428 |
graph: window.graphs[0].graph |
|
429 |
}); |
|
430 |
} |
|
431 |
} |
|
432 |
|
|
433 |
var hash_change_detector = function() { |
|
434 |
var new_fragment; |
|
435 |
|
|
436 |
// Pour les moments où on a besoin de mettre à jour |
|
437 |
// volontairement l'URI (à l'ouverture d'un graphe). |
|
438 |
if (window.skip_detection) return; |
|
439 |
|
|
440 |
// Force mootools à analyser l'URL courante de nouveau, |
|
441 |
// ce qui mettra à jour la partie "fragment" de l'URI. |
|
442 |
URI.base = new URI( |
|
443 |
document.getElements('base[href]', true).getLast(), |
|
444 |
{base: document.location} |
|
445 |
); |
|
446 |
|
|
447 |
new_fragment = new URI(); |
|
448 |
if (old_fragment.toString() != new_fragment.toString()) { |
|
449 |
update_visible_graphs(new_fragment, old_fragment); |
|
450 |
} |
|
451 |
}; |
|
452 |
|
|
453 |
if ('onhashchange' in window) { |
|
454 |
window.onhashchange = hash_change_detector; |
|
455 |
} else { |
|
456 |
hash_change_detector.periodical(100); |
|
457 |
} |
|
458 |
|
|
459 |
window.addEvent('load', function () { |
|
460 |
new Request.JSON({ |
|
461 |
url: app_path + 'rpc/tempoDelayRefresh', |
|
462 |
onSuccess: function (data) { |
|
463 |
window.refresh_delay = data.delay; |
|
464 |
} |
|
465 |
}).get(); |
|
466 |
|
|
467 |
hash_change_detector(); |
|
394 | 468 |
}); |
vigigraph/public/js/toolbar.js | ||
---|---|---|
28 | 28 |
}; |
29 | 29 |
this.tree.addEvent("branchloaded", adaptPopup.bind(this)); |
30 | 30 |
this.tree.addEvent("nodedisclosed", adaptPopup.bind(this)); |
31 |
|
|
32 | 31 |
}, |
33 | 32 |
|
34 | 33 |
setItem: function (idselection, label) { |
... | ... | |
118 | 117 |
}); |
119 | 118 |
window.open(uri.toString()); |
120 | 119 |
}.bind(this) |
121 |
}) |
|
120 |
});
|
|
122 | 121 |
|
123 | 122 |
this.show_metrology = new Jx.Button({ |
124 | 123 |
label: _('Metrology page'), |
... | ... | |
133 | 132 |
}); |
134 | 133 |
window.open(uri.toString()); |
135 | 134 |
}.bind(this) |
136 |
}) |
|
135 |
});
|
|
137 | 136 |
|
138 | 137 |
this.graph_label = new Jx.Toolbar.Item(this.createLabel(_('Graph:'))); |
139 | 138 |
|
... | ... | |
163 | 162 |
toggle: false, |
164 | 163 |
enabled: false, |
165 | 164 |
onClick: function () { |
166 |
new Graph(
|
|
165 |
new Graph( |
|
167 | 166 |
{autoRefresh: this.global_refresh.isActive() ? 1 : 0}, |
168 | 167 |
this.host_picker.getLabel(), |
169 | 168 |
this.graph_picker.getLabel() |
Also available in: Unified diff