rabbitmq-server/deps/rabbitmq_management/priv/www/js/main.js

709 lines
21 KiB
JavaScript
Raw Normal View History

var statistics_level;
var user_administrator;
var nodes_interesting;
var vhosts_interesting;
$(document).ready(function() {
statistics_level = JSON.parse(sync_get('/overview')).statistics_level;
var user = JSON.parse(sync_get('/whoami'));
replace_content('login', '<p>User: <b>' + user.name + '</b></p>');
user_administrator = user.administrator;
nodes_interesting = user_administrator &&
JSON.parse(sync_get('/nodes')).length > 1;
vhosts_interesting = JSON.parse(sync_get('/vhosts')).length > 1;
2010-10-08 00:23:11 +08:00
setup_constant_events();
2011-01-18 01:23:54 +08:00
current_vhost = get_pref('vhost');
2010-10-08 00:23:11 +08:00
update_vhosts();
app.run();
2011-01-18 02:06:02 +08:00
update_interval();
2010-07-13 20:03:36 +08:00
var url = this.location.toString();
if (url.indexOf('#') == -1) {
this.location = url + '#/';
}
});
2010-10-08 00:23:11 +08:00
function setup_constant_events() {
$('#update-every').change(function() {
var interval = $(this).val();
2011-01-18 02:06:02 +08:00
store_pref('interval', interval);
2010-10-08 00:23:11 +08:00
if (interval == '') interval = null;
set_timer_interval(interval);
});
$('#show-vhost').change(function() {
current_vhost = $(this).val();
2011-01-18 01:23:54 +08:00
store_pref('vhost', current_vhost);
2010-10-08 00:23:11 +08:00
update();
});
if (!vhosts_interesting) {
$('#vhost-form').hide();
}
2010-10-08 00:23:11 +08:00
}
function update_vhosts() {
var vhosts = JSON.parse(sync_get('/vhosts'));
vhosts_interesting = vhosts.length > 1;
if (vhosts_interesting)
$('#vhost-form').show();
else
$('#vhost-form').hide();
2010-10-08 00:23:11 +08:00
var select = $('#show-vhost').get(0);
select.options.length = vhosts.length + 1;
var index = 0;
for (var i = 0; i < vhosts.length; i++) {
var vhost = vhosts[i].name;
select.options[i + 1] = new Option(vhost);
if (vhost == current_vhost) index = i + 1;
}
select.selectedIndex = index;
2011-01-18 21:26:30 +08:00
current_vhost = select.options[index].text;
store_pref('vhost', current_vhost);
2010-10-08 00:23:11 +08:00
}
2011-01-18 02:06:02 +08:00
function update_interval() {
var interval = get_pref('interval');
interval = interval == null ? '5000' : interval;
set_timer_interval(interval);
var select = $('#update-every').get(0);
var opts = select.options;
for (var i = 0; i < opts.length; i++) {
if (opts[i].value == interval) {
select.selectedIndex = i;
break;
}
}
}
var app = $.sammy(dispatcher);
function dispatcher() {
var sammy = this;
function path(p, r, t) {
sammy.get(p, function() {
render(r, t, p);
});
}
this.get('#/', function() {
var reqs = {'overview': '/overview'};
if (user_administrator) {
reqs['nodes'] = '/nodes';
}
render(reqs, 'overview', '#/');
});
this.get('#/nodes/:name', function() {
var name = esc(this.params['name']);
render({'node': '/nodes/' + name},
'node', '');
});
2010-08-27 00:42:03 +08:00
2010-10-12 00:05:06 +08:00
path('#/connections', {'connections': '/connections'}, 'connections');
this.get('#/connections/:name', function() {
2010-10-14 23:55:34 +08:00
var name = esc(this.params['name']);
render({'connection': '/connections/' + name,
'channels': '/connections/' + name + '/channels'},
'connection', '#/connections');
});
this.del('#/connections', function() {
if (sync_delete(this, '/connections/:name'))
go_to('#/connections');
return false;
});
2010-08-27 00:42:03 +08:00
path('#/channels', {'channels': '/channels'}, 'channels');
2010-09-03 00:06:59 +08:00
this.get('#/channels/:name', function() {
render({'channel': '/channels/' + esc(this.params['name'])}, 'channel',
'#/channels');
});
2010-08-27 00:42:03 +08:00
path('#/exchanges', {'exchanges': '/exchanges', 'vhosts': '/vhosts'}, 'exchanges');
2010-08-27 00:42:03 +08:00
this.get('#/exchanges/:vhost/:name', function() {
var path = '/exchanges/' + esc(this.params['vhost']) + '/' + esc(this.params['name']);
render({'exchange': path,
'bindings_source': path + '/bindings/source',
'bindings_destination': path + '/bindings/destination'},
'exchange', '#/exchanges');
2010-08-27 00:42:03 +08:00
});
this.put('#/exchanges', function() {
if (sync_put(this, '/exchanges/:vhost/:name'))
update();
2010-08-27 00:42:03 +08:00
return false;
});
this.del('#/exchanges', function() {
if (sync_delete(this, '/exchanges/:vhost/:name'))
go_to('#/exchanges');
2010-08-27 00:42:03 +08:00
return false;
});
path('#/queues', {'queues': '/queues', 'vhosts': '/vhosts'}, 'queues');
2010-08-27 17:55:32 +08:00
this.get('#/queues/:vhost/:name', function() {
2010-09-02 00:26:51 +08:00
var path = '/queues/' + esc(this.params['vhost']) + '/' + esc(this.params['name']);
render({'queue': path,
'bindings': path + '/bindings'}, 'queue', '#/queues');
2010-08-27 17:55:32 +08:00
});
this.put('#/queues', function() {
if (sync_put(this, '/queues/:vhost/:name'))
update();
2010-08-27 17:55:32 +08:00
return false;
});
this.del('#/queues', function() {
2010-10-01 00:49:28 +08:00
if (this.params['mode'] == 'delete') {
if (sync_delete(this, '/queues/:vhost/:name'))
go_to('#/queues');
}
else if (this.params['mode'] == 'purge') {
if (sync_delete(this, '/queues/:vhost/:name/contents')) {
error_popup('info', "Queue purged");
update_partial();
2010-10-01 00:49:28 +08:00
}
}
2010-08-27 17:55:32 +08:00
return false;
});
2010-08-27 00:42:03 +08:00
2010-09-02 00:26:51 +08:00
this.post('#/bindings', function() {
if (sync_post(this, '/bindings/:vhost/e/:source/:destination_type/:destination'))
update();
2010-09-02 00:26:51 +08:00
return false;
});
this.del('#/bindings', function() {
if (sync_delete(this, '/bindings/:vhost/e/:source/:destination_type/:destination/:properties_key'))
update();
2010-09-02 00:26:51 +08:00
return false;
});
2010-10-12 00:05:06 +08:00
path('#/vhosts', {'vhosts': '/vhosts'}, 'vhosts');
this.get('#/vhosts/:id', function() {
render({'vhost': '/vhosts/' + esc(this.params['id']),
'permissions': '/vhosts/' + esc(this.params['id']) + '/permissions',
'users': '/users/'},
'vhost', '#/vhosts');
});
this.put('#/vhosts', function() {
2010-10-08 00:23:11 +08:00
if (sync_put(this, '/vhosts/:name')) {
update_vhosts();
update();
2010-10-08 00:23:11 +08:00
}
return false;
});
this.del('#/vhosts', function() {
2010-10-08 00:23:11 +08:00
if (sync_delete(this, '/vhosts/:name')) {
update_vhosts();
go_to('#/vhosts');
2010-10-08 00:23:11 +08:00
}
return false;
});
2010-08-27 00:42:03 +08:00
2010-10-12 00:05:06 +08:00
path('#/users', {'users': '/users'}, 'users');
this.get('#/users/:id', function() {
render({'user': '/users/' + esc(this.params['id']),
2010-09-02 00:45:05 +08:00
'permissions': '/users/' + esc(this.params['id']) + '/permissions',
'vhosts': '/vhosts/'}, 'user',
'#/users');
});
this.put('#/users', function() {
if (sync_put(this, '/users/:username'))
update();
return false;
});
this.del('#/users', function() {
if (sync_delete(this, '/users/:username'))
go_to('#/users');
return false;
});
2010-08-27 00:42:03 +08:00
this.put('#/permissions', function() {
if (sync_put(this, '/permissions/:vhost/:username'))
update();
return false;
});
this.del('#/permissions', function() {
if (sync_delete(this, '/permissions/:vhost/:username'))
update();
return false;
});
this.get('#/import-succeeded', function() {
render({}, 'import-succeeded', '#/overview');
});
}
function go_to(url) {
this.location = url;
}
var current_template;
var current_reqs;
var current_highlight;
2010-10-08 00:23:11 +08:00
var current_vhost = '';
2010-10-12 00:05:06 +08:00
var current_sort;
var current_sort_reverse = false;
var timer;
var timer_interval;
function set_timer_interval(interval) {
timer_interval = interval;
reset_timer();
}
function reset_timer() {
clearInterval(timer);
if (timer_interval != null) {
2010-09-29 23:56:03 +08:00
timer = setInterval('partial_update()', timer_interval);
}
}
function render(reqs, template, highlight) {
current_template = template;
current_reqs = reqs;
current_highlight = highlight;
2010-09-29 23:56:03 +08:00
update();
}
2010-09-29 23:56:03 +08:00
function update() {
clearInterval(timer);
2010-10-08 00:23:11 +08:00
with_update(function(html) {
replace_content('main', html);
postprocess();
2010-10-12 00:05:06 +08:00
postprocess_partial();
reset_timer();
});
2010-07-13 20:03:36 +08:00
}
2010-09-29 23:56:03 +08:00
function partial_update() {
if ($('.updatable').length > 0) {
2010-10-08 00:23:11 +08:00
with_update(function(html) {
replace_content('scratch', html);
var befores = $('#main .updatable');
var afters = $('#scratch .updatable');
if (befores.length != afters.length) {
throw("before/after mismatch");
}
for (var i = 0; i < befores.length; i++) {
befores[i].innerHTML = afters[i].innerHTML;
}
2010-10-12 00:05:06 +08:00
postprocess_partial();
});
}
}
2010-10-08 00:23:11 +08:00
function with_update(fun) {
2010-10-12 00:05:06 +08:00
with_reqs(apply_state(current_reqs), [], function(json) {
json.statistics_level = statistics_level;
var html = format(current_template, json);
fun(html);
update_status('ok');
});
}
2010-10-12 00:05:06 +08:00
var VHOST_QUERIES = map(['/queues', '/exchanges']);
var SORT_QUERIES = map(['/connections', '/channels', '/vhosts', '/users',
'/queues', '/exchanges']);
function map(list) {
var res = {};
for (i in list) {
res[list[i]] = '';
2010-10-08 00:23:11 +08:00
}
2010-10-12 00:05:06 +08:00
return res;
}
function apply_state(reqs) {
var reqs2 = {};
for (k in reqs) {
var req = reqs[k];
var req2;
if (req in VHOST_QUERIES && current_vhost != '') {
req2 = req + '/' + esc(current_vhost);
}
else {
req2 = req;
2010-10-08 00:23:11 +08:00
}
2010-10-12 00:05:06 +08:00
var qs = '';
if (req in SORT_QUERIES && current_sort != null) {
qs = '?sort=' + current_sort +
'&sort_reverse=' + current_sort_reverse;
}
reqs2[k] = req2 + qs;
2010-10-08 00:23:11 +08:00
}
2010-10-12 00:05:06 +08:00
return reqs2;
2010-10-08 00:23:11 +08:00
}
function error_popup(type, text) {
var cssClass = '.form-popup-' + type;
function hide() {
$(cssClass).slideUp(200, function() {
$(this).remove();
});
}
hide();
$('h1').after(format('error-popup', {'type': type, 'text': text}));
$(cssClass).center().slideDown(200);
$(cssClass + ' span').click(hide);
}
function postprocess() {
$('a').removeClass('selected');
$('a[href="' + current_highlight + '"]').addClass('selected');
2010-08-24 17:24:50 +08:00
$('form.confirm').submit(function() {
return confirm("Are you sure? This object cannot be recovered " +
"after deletion.");
});
$('div.section h2, div.section-hidden h2').click(function() {
toggle_visibility($(this));
});
$('label').map(function() {
if ($(this).attr('for') == '') {
var id = 'auto-label-' + Math.floor(Math.random()*1000000000);
var input = $(this).parents('tr').first().find('input, select');
if (input.attr('id') == '') {
$(this).attr('for', id);
input.attr('id', id);
}
}
});
$('#download-configuration').click(function() {
var path = '/api/all-configuration?download=' +
esc($('#download-filename').val());
window.location = path;
setTimeout('app.run()');
return false;
});
2010-10-12 21:08:17 +08:00
$('.multifield input').live('blur', function() {
update_multifields();
});
2010-12-09 01:40:10 +08:00
$('#has-password').change(function() {
if ($(this).val() == 'true') {
$('#password').slideDown(100);
2010-12-09 21:50:19 +08:00
$('#no-password').slideUp(100);
2010-12-09 01:40:10 +08:00
} else {
$('#password').slideUp(100);
2010-12-09 21:50:19 +08:00
$('#no-password').slideDown(100);
2010-12-09 01:40:10 +08:00
}
});
setup_visibility();
if (! user_administrator) {
$('.administrator-only').remove();
}
2010-10-12 21:08:17 +08:00
update_multifields();
}
2010-10-12 00:05:06 +08:00
function postprocess_partial() {
$('.sort').click(function() {
var sort = $(this).attr('sort');
if (current_sort == sort) {
current_sort_reverse = ! current_sort_reverse;
}
else {
current_sort = sort;
current_sort_reverse = false;
}
update();
});
}
2010-10-12 21:08:17 +08:00
function update_multifields() {
$('.multifield').each(function(index) {
var largest_id = 0;
var empty_found = false;
var name = $(this).attr('id');
$('input[name$="_mfkey"]').each(function(index) {
var match = $(this).attr('name').
match(/[a-z]*_([0-9]*)_mfkey/);
var id = parseInt(match[1]);
largest_id = Math.max(id, largest_id);
var key = $(this).val();
var value = $(this).next('input').val();
if (key == '' && value == '') {
if (empty_found) {
$(this).parent().remove();
}
else {
empty_found = true;
}
}
});
if (!empty_found) {
$(this).append('<p><input type="text" name="' + name + '_' +
(largest_id + 1) +
'_mfkey" value=""/> = ' +
'<input type="text" name="' + name + '_' +
(largest_id + 1) +
'_mfvalue" value=""/></p>');
}
});
}
function setup_visibility() {
$('div.section,div.section-hidden').each(function(_index) {
var pref = section_pref(current_template,
$(this).children('h2').text());
var show = get_pref(pref);
if (show == null) {
show = $(this).hasClass('section');
}
else {
show = show == 't';
}
if (show) {
$(this).addClass('section-visible');
}
else {
$(this).addClass('section-invisible');
}
});
}
function toggle_visibility(item) {
var hider = item.next();
var all = item.parent();
var pref = section_pref(current_template, item.text());
item.next().slideToggle(100);
if (all.hasClass('section-visible')) {
if (all.hasClass('section'))
store_pref(pref, 'f');
else
clear_pref(pref);
all.removeClass('section-visible');
all.addClass('section-invisible');
}
else {
if (all.hasClass('section-hidden'))
store_pref(pref, 't');
else
clear_pref(pref);
all.removeClass('section-invisible');
all.addClass('section-visible');
}
}
function with_reqs(reqs, acc, fun) {
if (keys(reqs).length > 0) {
var key = keys(reqs)[0];
with_req('/api' + reqs[key], function(resp) {
acc[key] = jQuery.parseJSON(resp.responseText);
var remainder = {};
for (var k in reqs) {
if (k != key) remainder[k] = reqs[k];
}
with_reqs(remainder, acc, fun);
});
}
else {
fun(acc);
}
}
2010-07-13 00:31:16 +08:00
function replace_content(id, html) {
$("#" + id).empty();
$(html).appendTo("#" + id);
}
function format(template, json) {
try {
var tmpl = new EJS({url: 'js/tmpl/' + template + '.ejs'});
return tmpl.render(json);
} catch (err) {
clearInterval(timer);
debug(err['name'] + ": " + err['message']);
}
}
function update_status(status) {
2010-07-13 00:31:16 +08:00
var text;
if (status == 'ok')
text = "Last update: " + new Date();
2010-07-13 00:31:16 +08:00
else if (status == 'error')
text = "Error: could not connect to server at " + new Date();
else
throw("Unknown status " + status);
2010-07-13 00:31:16 +08:00
var html = format('status', {status: status, text: text});
2010-07-13 00:31:16 +08:00
replace_content('status', html);
}
function with_req(path, fun) {
var json;
var req = xmlHttpRequest();
req.open( "GET", path, true );
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
fun(req);
}
2010-07-13 00:31:16 +08:00
else if (req.status == 408) {
update_status('timeout');
2010-07-13 00:31:16 +08:00
}
else if (req.status == 0) { // Non-MSIE: could not connect
update_status('error');
}
else if (req.status > 12000) { // MSIE: could not connect
update_status('error');
}
2010-07-24 00:24:01 +08:00
else if (req.status == 404) {
var html = format('404', {});
replace_content('main', html);
}
else {
debug("Got response code " + req.status);
clearInterval(timer);
}
}
};
req.send(null);
}
2010-07-13 20:03:36 +08:00
function sync_get(path) {
return sync_req('GET', [], path);
}
2010-08-25 01:46:30 +08:00
function sync_put(sammy, path_template) {
return sync_req('PUT', sammy.params, path_template);
2010-08-25 01:46:30 +08:00
}
function sync_delete(sammy, path_template) {
return sync_req('DELETE', sammy.params, path_template);
2010-08-25 01:46:30 +08:00
}
2010-09-02 00:26:51 +08:00
function sync_post(sammy, path_template) {
return sync_req('POST', sammy.params, path_template);
2010-09-02 00:26:51 +08:00
}
2010-10-12 21:08:17 +08:00
function sync_req(type, params0, path_template) {
2010-12-09 01:40:10 +08:00
var params = params_magic(params0);
var path;
try {
path = fill_path_template(path_template, params);
} catch (e) {
error_popup('warn', e);
return false;
}
var req = xmlHttpRequest();
2010-08-31 21:22:52 +08:00
req.open(type, '/api' + path, false);
req.setRequestHeader('content-type', 'application/json');
try {
if (type == 'GET')
req.send(null);
else
req.send(JSON.stringify(params));
}
catch (e) {
if (e.number == 0x80004004) {
// 0x80004004 means "Operation aborted."
// http://support.microsoft.com/kb/186063
// MSIE6 appears to do this in response to HTTP 204.
}
}
if (req.status >= 400 && req.status <= 404) {
var reason = JSON.parse(req.responseText).reason;
if (typeof(reason) != 'string') reason = JSON.stringify(reason);
error_popup('warn', reason);
return false;
}
// 1223 == 204 - see http://www.enhanceie.com/ie/bugs.asp
// MSIE7 and 8 appear to do this in response to HTTP 204.
if (req.status >= 400 && req.status != 1223) {
debug("Got response code " + req.status + " with body " +
req.responseText);
}
if (type == 'GET')
return req.responseText;
else
return true;
}
2010-07-13 20:03:36 +08:00
2010-08-25 01:46:30 +08:00
function fill_path_template(template, params) {
var re = /:[a-zA-Z_]*/g;
return template.replace(re, function(m) {
var str = esc(params[m.substring(1)]);
if (str == '') {
throw(m.substring(1) + " is required");
}
return str;
2010-08-25 01:46:30 +08:00
});
}
2010-10-12 21:08:17 +08:00
// Better suggestions appreciated
var INTEGER_ARGUMENTS = map(['x-expires']);
2010-12-09 01:40:10 +08:00
function params_magic(params) {
return maybe_remove_password(
collapse_multifields(params));
}
2010-10-12 21:08:17 +08:00
function collapse_multifields(params0) {
var params = {};
for (key in params0) {
var match = key.match(/([a-z]*)_([0-9]*)_mfkey/);
var match2 = key.match(/[a-z]*_[0-9]*_mfvalue/);
if (match == null && match2 == null) {
params[key] = params0[key];
}
else if (match == null) {
// Do nothing, value is handled below
}
else {
var name = match[1];
var id = match[2];
if (params[name] == undefined) {
params[name] = {};
}
if (params0[key] != "") {
var k = params0[key];
var v = params0[name + '_' + id + '_mfvalue'];
if (k in INTEGER_ARGUMENTS) {
v = parseInt(v);
}
params[name][k] = v;
}
}
}
return params;
}
2010-12-09 01:40:10 +08:00
function maybe_remove_password(params) {
if (params['has-password'] == 'false') {
delete params['password'];
}
return params;
}
2010-07-13 20:03:36 +08:00
function debug(str) {
$('<p>' + str + '</p>').appendTo('#debug');
}
function keys(obj) {
var ks = [];
for (var k in obj) {
ks.push(k);
}
return ks;
}
// Don't use the jQuery AJAX support, it seemss to have trouble reporting
// server-down type errors.
function xmlHttpRequest() {
var res;
try {
res = new XMLHttpRequest();
}
catch(e) {
res = new ActiveXObject("Microsoft.XMLHttp");
}
return res;
}
(function($){
$.fn.extend({
center: function () {
return this.each(function() {
var top = ($(window).height() - $(this).outerHeight()) / 2;
var left = ($(window).width() - $(this).outerWidth()) / 2;
$(this).css({margin:0, top: (top > 0 ? top : 0)+'px', left: (left > 0 ? left : 0)+'px'});
});
}
});
})(jQuery);