frontend/dcmgr_gui/public/javascripts/dcmgr_gui/core.js
window.DcmgrGUI = function(){};
//Refarence:http://wp.serpere.info/archives/1091
DcmgrGUI.Class = (function() {
function subclass() {}
return {
create: function(parent) {
function klass() {
this.initialize.apply(this, arguments);
}
var index = 0;
if(jQuery.isFunction(parent)) {
index = 1;
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
}
for(; index < arguments.length; ++index) {
jQuery.extend(klass.prototype, arguments[index]);
}
return klass;
}
}
})();
DcmgrGUI.Request = DcmgrGUI.Class.create({
initialize: function(){
dcmgrGUI.setConfig('error_popup', true);
},
get: function(params){
params['type'] = 'GET';
return this._request(params);
},
put: function(params){
params['type'] = 'PUT';
return this._request(params);
},
post: function(params){
params['type'] = 'POST';
return this._request(params);
},
del: function(params){
params['type'] = 'DELETE';
return this._request(params);
},
_request: function(params){
if (params['async'] == undefined) {
params['async'] = true;
}
params['dataType'] = 'json';
params['cache'] = false;
return $.ajax(params);
}
});
DcmgrGUI.Filter = DcmgrGUI.Class.create({
initialize: function(){
this.filters = [];
},
add: function(filter){
this.filters.push(filter);
},
execute: function(data){
this.apply(0,data);
},
apply: function(index,data){
if (this.filters[index] && typeof this.filters[index] === "function") {
this.filters[index](data);
var next_index = index + 1;
if (this.filters[next_index]) {
this.apply(next_index,data);
} else {
return data;
}
}
}
});
DcmgrGUI.Converter = {};
// Convert byte size to display byte unit in
// appropriate byte unit (MB, GB, TB, PB...).
// < 1GB is displayed: 100MB
// > 1GB is displayed: 10 GB, 101GB, 1TB
displayDiskSize = DcmgrGUI.Converter.toDisplayDiskSize = function(qty, in_unit) {
if (qty === undefined || qty == ''){
return "";
}
if (in_unit === undefined ){ in_unit = 'B'; }
var BYTEUNITS= {
'B' : 1,
'KB': 1024,
'MB': Math.pow(1024, 2),
'GB': Math.pow(1024, 3),
'TB': Math.pow(1024, 4),
'PB': Math.pow(1024, 5),
'EB': Math.pow(1024, 6),
'EB': Math.pow(1024, 7),
'ZB': Math.pow(1024, 8),
'YB': Math.pow(1024, 9)
};
qty = qty * BYTEUNITS[in_unit.toUpperCase()];
if( qty < BYTEUNITS['GB'] ){
return (qty / BYTEUNITS['MB']) + 'MB';
}else {
var u = _.find(_.keys(BYTEUNITS), function(i){
return qty < BYTEUNITS[i];
});
return (qty / BYTEUNITS[u]) + u;
}
};
DcmgrGUI.Converter.unit = function(data, unit_type){
var unit = '';
switch(unit_type) {
case 'megabyte':
unit = 'MB';
break;
case 'gigabyte':
unit = 'GB';
break;
}
return data + unit;
};
DcmgrGUI.date = {};
DcmgrGUI.date.parseISO8601 = function (str) {
/*
Reference: http://anentropic.wordpress.com/2009/06/25/javascript-iso8601-parser-and-pretty-dates/
*/
// we assume str is a UTC date ending in 'Z'
var parts = str.split('T'),
dateParts = parts[0].split('-'),
timeParts = parts[1].split('Z'),
timeSubParts = timeParts[0].split(':'),
timeSecParts = timeSubParts[2].split('.'),
timeHours = Number(timeSubParts[0]),
_date = new timezoneJS.Date();
_date.setUTCFullYear(Number(dateParts[0]));
_date.setUTCMonth(Number(dateParts[1] - 1 ));
_date.setUTCDate(Number(dateParts[2]));
_date.setUTCHours(Number(timeHours));
_date.setUTCMinutes(Number(timeSubParts[1]));
_date.setUTCSeconds(Number(timeSecParts[0]));
if (timeSecParts[1]) _date.setUTCMilliseconds(Number(timeSecParts[1]));
// by using setUTC methods the date has already been converted to local time(?)
return _date;
};
DcmgrGUI.date.setTimezone = function(date_str, timezone){
date_str.setTimezone(timezone);
return date_str;
};
DcmgrGUI.date.setTimezoneOffset = function(date_str, utc_offset){
date_str.setUTCSeconds(utc_offset);
return date_str;
};
DcmgrGUI.date.getI18n = function(date_str){
var convert = function(value) {
return ("0" + value).slice(-2);
}
return $.i18n.prop('display_date', [date_str.getUTCFullYear(),
convert(date_str.getMonth() + 1),
convert(date_str.getDate()),
convert(date_str.getHours()),
convert(date_str.getMinutes()),
convert(date_str.getSeconds())
]);
};
// Convert UTC ISO8601 time string to local TZ with I18n.
DcmgrGUI.date.utcToLocal = function(iso8601_date_str) {
// TODO: cleanup white spaces in date_str.
try {
return DcmgrGUI.date.getI18n(DcmgrGUI.date.setTimezone(DcmgrGUI.date.parseISO8601(iso8601_date_str),
dcmgrGUI.getConfig('time_zone')
));
} catch(a) {
return iso8601_date_str;
}
};
DcmgrGUI.Pagenate = DcmgrGUI.Class.create({
initialize: function(params) {
var self = this;
this.element = $('#pagenate');
this.view = $("#viewPagenate").text();
this.total = params.total;
this.page_count = this.getPageCount(params['total'],params['row']);
this.current_page = 1;
this.row = params['row'];
this.start = this.getStartCount();
this.offset = this.getOffsetCount();
this.prev = DcmgrGUI.Util.createUIButton(this.element.find('.prev'),{
disabled : true,
text : false
});
this.next = DcmgrGUI.Util.createUIButton(this.element.find('.next'),{
disabled : true,
text : false
});
this.prev.bind("click",{obj: this},function(event){
var self = event.data.obj;
if (self.prev.button("option","disabled")) {
return false;
};
self.updatePage.call(this,event);
self.changeArrowButton();
});
this.next.bind("click",{obj: this},function(event){
var self = event.data.obj;
if (self.next.button("option","disabled")) {
return false;
};
self.updatePage.call(this,event);
self.changeArrowButton();
});
this.renderPagenate();
//create topics
dcmgrGUI.notification.create_topic('change_pagenate');
},
changeArrowButton: function() {
if (this.current_page === 1){
this.prev.button("option", "disabled", true);
this.next.button("option", "disabled", false);
}else{
if (this.current_page === this.page_count) {
this.prev.button("option", "disabled", false);
this.next.button("option", "disabled", true);
} else {
this.prev.button("option", "disabled", false);
this.next.button("option", "disabled", false);
}
}
},
getPageCount: function(total,row){
return Math.ceil(total / row);
},
changeTotal: function(total){
this.total = total;
if(this.total > (this.current_page * this.row)) {
this.next.button("option", "disabled", false);
}else{
this.next.button("option", "disabled", true);
}
this.page_count = this.getPageCount(this.total,this.row)
this.renderPagenate();
},
changePage: function() {
var self = this;
var current_page = $('#viewPagenate').find("#current_page");
if(current_page.length != 0) {
current_page.bind("focus", function(){
this.select();
});
current_page.bind("keypress", function(event){
if(event.keyCode == 13) {
var page = parseInt(current_page.val());
self.current_page = page;
self.page = page;
event.data = {'obj': self};
self.updatePage.call(this, event);
self.changeArrowButton();
}
});
}
},
renderPagenate: function(){
this.start = this.getStartCount();
this.offset = this.getOffsetCount();
if (this.start !== 0 && this.offset !==0 ) {
var current_page = '<input type="text" id="current_page" style="width:20px;height:13px" value="'+ this.current_page +'">';
var page = $.i18n.prop('page_pagenate', [this.page_count]);
var total = $.i18n.prop('total_pagenate', [this.total]);
var html = current_page + ' / ' + page + ' : ' + total;
html += ' ' + this.view;
} else{
var html = '';
}
$("#viewPagenate").html(html);
this.changePage();
},
updatePage: function(event){
var self = event.data.obj;
if($(this).attr('class')) {
var name = $(this).attr('class').split(' ')[0];
}
if(self.current_page >= 1 && self.current_page < self.page_count) {
if(name === 'next'){
self.next_page = self.current_page +1;
self.current_page = self.next_page;
}
}
if(self.current_page > 1 && self.current_page <= self.page_count){
if(name === 'prev'){
self.prev_page = self.current_page -1;
self.current_page = self.prev_page;
}
}
self.renderPagenate();
self.element.trigger('dcmgrGUI.updatePagenate');
dcmgrGUI.notification.publish('change_pagenate');
},
getOffsetCount: function(){
var count = (this.current_page * this.row);
if (this.total < count) {
return this.total;
} else {
return count;
}
},
getStartCount: function(){
if (this.current_page === 1) {
var start = 1;
} else {
var start = ((this.current_page -1) * this.row) + 1;
}
return start;
}
});
DcmgrGUI.Dialog = DcmgrGUI.Class.create({
initialize: function(params) {
this.target = $(params['target']);
this.element = $('<div></div>');
this.path_prefix = '/dialog';
this.path = this.path_prefix + params['path'];
this.width = params['width'];
this.height = params['height'];
this.title = params['title'];
this.button = params['button'];
this.callback = params['callback'] ||null;
dcmgrGUI.notification.create_topic('close_dialog');
},
open: function(params){
//multi select action
if(params){
if(params.ids.length == 0){
return false;
}
this.create(params);
}else{
//new create action
this.create();
}
this.content.dialog('open');
},
getWidgetButton: function(num) {
var widget = $(this.content.dialog('widget')
.find(".ui-button-text")[num]);
return widget;
},
disabledButton: function(num, disabled){
var widget = this.getWidgetButton(num);
if( widget ) {
widget.parent().button("option", "disabled", disabled);
}
},
close: function(){
this.content.dialog('close');
},
enableDialogButton: function(){
$(this.target).button({ disabled: false });
},
disableDialogButton: function(){
$(this.target).button({ disabled: true });
},
is_disabled: function(){
return $(this.target).button("option", "disabled");
},
create: function(params){
//initialize
this.element = $('<div></div>');
this.content = this.element
.load(this.path + '?_=' + (new Date()).getTime(),
params,
this.callback)
.dialog({
title: this.title,
disable: false,
autoOpen: false,
bgiframe: true,
width: this.width,
height: this.height,
modal: true,
resizable: true,
closeOnEscape: true,
closeText: 'hide',
draggable:false,
buttons: this.button,
close: function(event, ui) {
dcmgrGUI.notification.publish('close_dialog');
}
});
}
});
DcmgrGUI.ContentBase = DcmgrGUI.Class.create({
initialize: function(params){
if (params.element_id) {
this.element = $(params.element_id);
} else {
this.element = $('<div></div>');
}
this.template = params.template_id;
this.filter = new DcmgrGUI.Filter();
},
update:function(params,async){
var self = this;
try{
$("#list_load_mask").mask($.i18n.prop('loading_parts'));
self.element.trigger('dcmgrGUI.beforeUpdate');
var request = new DcmgrGUI.Request;
request.get({
url: params.url,
data: params.data,
success: function(json,status,xhr){
self.filter.execute(json);
self.element.trigger('dcmgrGUI.contentChange',[{"data":json,"self":self}]);
self.element.trigger('dcmgrGUI.afterUpdate',[{"data":json,"self":self}]);
},
complete: function(xhr, status) {
$("#list_load_mask").unmask();
}
});
} catch( e ) {
$("#list_load_mask").unmask();
}
}
});
DcmgrGUI.Util = {};
DcmgrGUI.Util.getPagePath = function(path,page,format){
var format = format||'json';
return path + page + '.' + format;
};
DcmgrGUI.Util.setfillData = function(maxrows,json){
var fillCount = maxrows-json.length;
var emptyObj = [];
for (var key in json[0]) {
emptyObj.key = '';
}
for(var i=0;i<fillCount;i++){
json.push(emptyObj);
}
return json;
};
DcmgrGUI.Util.getLoadingImage = function(type){
switch(type) {
case "ball":
var image = 'loader_ball.gif';
break;
case "boxes":
var image = 'loader_boxes.gif';
break;
default:
var image = 'loader_ball.gif';
break;
}
return '<img src="images/'+image+'" />';
};
DcmgrGUI.Util.getPagenateData = function(start,limit){
return "start=" + start + "&" + "limit=" + limit;
};
DcmgrGUI.Util.createUIButton = function(element,options){
return element
.button(options)
.removeClass("ui-state-default")
.removeClass("ui-button")
.removeClass("ui-corner-all")
.hover(function(){
element.removeClass("ui-state-hover");
})
.focus(function(){
element.removeClass("ui-state-focus");
});
};
DcmgrGUI.Util.availableTextField = function(e){
var d = e.data;
var button = d.button;
var element_id = d.element_id;
if(_.include(['paste', 'cut'], e.type)) {
var el = $(this);
setTimeout(function() {
var text = $(el).val();
if(text) {
button.disabledButton(element_id, false);
} else {
button.disabledButton(element_id, true);
}
}, 100);
} else {
var text = $(this).val();
if(text) {
button.disabledButton(element_id, false);
} else {
button.disabledButton(element_id, true);
}
}
return true;
};
DcmgrGUI.Util.checkTextField = function(e) {
var d = e.data;
var name = d.name;
var is_ready = d.is_ready;
var ready = d.ready;
if(_.include(['paste', 'cut'], e.type)) {
var el = $(this);
setTimeout(function(){
var text = $(el).val();
if(text) {
is_ready[name] = true;
ready(is_ready);
} else {
is_ready[name] = false;
ready(is_ready);
}
}, 100);
} else {
var text = $(this).val();
if(text) {
is_ready[name] = true;
ready(is_ready);
} else {
is_ready[name] = false;
ready(is_ready);
}
}
return true;
};
// Find ISO8601 UTC string in the HTML element and convert it.
DcmgrGUI.Util.utcToLocal = function(elemid) {
var elem = $(elemid);
elem.html(DcmgrGUI.date.utcToLocal(elem.html()));
};
DcmgrGUI.Util.nl2br = function(value){
return value.replace(/(\r\n|\n\r|\r|\n)/g,"<br />");
};
DcmgrGUI.Util.slice = function(length, value){
return value.slice(0, length) + '...'
};
DcmgrGUI.Event = DcmgrGUI.Class.create({
initialize: function(){
this.events = {};
},
attach: function(event_name, func){
if(!this.events[event_name] && typeof func === "function") {
this.events[event_name] = func;
}
},
detach: function(event_name){
if(this.events[event_name]) {
delete this.events[event_name];
}
},
fire: function(event_name){
if(this.events[event_name]) {
this.events[event_name]();
}
}
});
DcmgrGUI.Notification = DcmgrGUI.Class.create({
initialize: function() {
this.topics = {};
this.evaluation_list = {};
this.subscription_id = 1;
},
create_topic: function(topic_id) {
if(!this.topics[topic_id]) {
this.topics[topic_id] = [];
}
},
subscribe: function(topic_id, target, method_name, options) {
if( this.topics[topic_id] ) {
this.topics[topic_id].push({'target': target,
'method_name': method_name,
'options': options,
'subscription_id': this.subscription_id});
var subscription_id = this.subscription_id;
this.subscription_id += 1;
return subscription_id;
}
},
add_evaluation: function(subscription_id, logic) {
this.evaluation_list[subscription_id] = logic;
},
evaluate: function(subscription_id) {
if(jQuery.isFunction(this.evaluation_list[subscription_id])) {
return this.evaluation_list[subscription_id]();
} else{
return true;
}
},
publish: function(topic_id) {
if(this.topics[topic_id]) {
var size = this.topics[topic_id].length;
for (i=0; i < size; i++) {
var topic = this.topics[topic_id][i];
var target = topic['target'];
var method_name = topic['method_name'];
if(this.evaluate(topic['subscription_id'])) {
target[method_name](topic['options']);
}
}
}
}
});
DcmgrGUI.List = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
initialize: function(params){
DcmgrGUI.ContentBase.prototype.initialize(params);
this.checked_list = {};
this.detail_template = {};
this.maxrow = params.maxrow;
this.page = params.page;
this.detail_filter = new DcmgrGUI.Filter();
this.detail_filter.add(function(data){
if(data.item.created_at) {
data.item.created_at = DcmgrGUI.date.parseISO8601(data.item.created_at);
data.item.created_at = DcmgrGUI.date.setTimezone(data.item.created_at, dcmgrGUI.getConfig('time_zone'));
data.item.created_at = DcmgrGUI.date.getI18n(data.item.created_at);
}
if(data.item.updated_at) {
data.item.updated_at = DcmgrGUI.date.parseISO8601(data.item.updated_at);
data.item.updated_at = DcmgrGUI.date.setTimezone(data.item.updated_at, dcmgrGUI.getConfig('time_zone'));
data.item.updated_at = DcmgrGUI.date.getI18n(data.item.updated_at);
}
if(data.item.last_login_at) {
data.item.last_login_at = DcmgrGUI.date.parseISO8601(data.item.last_login_at);
data.item.last_login_at = DcmgrGUI.date.setTimezone(data.item.last_login_at, dcmgrGUI.getConfig('time_zone'));
data.item.last_login_at = DcmgrGUI.date.getI18n(data.item.last_login_at);
}
return data;
});
var self = this;
this.element.bind('dcmgrGUI.afterUpdate',function(event){
var bg;
var kids;
$("table").find('td').hover(
function () {
//Mouse over
bg = $(this).parent().css("background-color");
kids = $(this).parent().children();
kids.css("background-color","#82c9d9");
},
function () {
//Mouse over
kids.css("background-color",bg);
}
);
self.element.find("[type='checkbox']").each(function(key,value){
var id = $(value).val();
if(self.checked_list[id]){
$(event.target).find("[type='checkbox']").each(function(){
if($(this).val() === id){
$(this).attr('checked',true);
}
});
}
});
});
this.element.bind('dcmgrGUI.updateList',function(event,params){
self.update(params.request,true);
});
dcmgrGUI.notification.create_topic('checked_box');
dcmgrGUI.notification.create_topic('unchecked_box');
dcmgrGUI.notification.create_topic('checked_radio');
},
setDetailTemplate:function(template){
this.detail_template = template;
},
getCheckedInstanceIds:function(){
var ids = [];
for(var id in this.checked_list){
ids.push(id);
}
return {
'ids':ids
};
},
checkRadioButton:function(id){
$('#'+id).attr("checked", true);
},
setData:function(json){
var rows = [];
if(!json){
rows = this.getEmptyData();
}else{
$.each(json,function(key,value){
rows.push(value.result);
});
}
var row = this.maxrow || 10;
var data = {
rows:DcmgrGUI.Util.setfillData(row,rows)
};
this.element.html('');
if(data.rows){
$( this.template )
.tmpl( data )
.appendTo( this.element );
}
},
clearCheckedList:function(){
this.checked_list = {};
},
changeStatus:function(state){
$.each(this.checked_list,function(id,obj){
obj.element.find('.state').html(state);
$('#detail').find('#'+id).find('.state').html(state);
});
},
currentChecked:function(){
var id = this.element.find("[type='radio']:checked").val();
if( id ){
return id;
}else{
return null;
}
},
currentMultiChecked:function(){
var checked_list = this.element.find("[type='checkbox']:checked");
var ids = [];
$.each(checked_list, function(key, item){
ids.push($(item).val());
})
return {
'ids':ids
};
},
singleCheckList:function(params){
var self = this;
this.element.find("[type='radio']").each(function(key,value){
$(this).click(function(){
var check_id = $(this).val();
if($(this).is(':checked')){
dcmgrGUI.notification.publish('checked_radio');
var c_detail = new DcmgrGUI.Detail({
template_id:params.template_id
});
c_detail.element.bind('dcmgrGUI.contentChange',function(event,params){
var data = { item:params.data };
//initialize
if(!params.data){
data.item = self.getEmptyData();
}
if(data.item){
self.detail_filter.execute(data);
$('#detail').html($( c_detail.template ).tmpl(data));
}
});
c_detail.update({
url:DcmgrGUI.Util.getPagePath(params.detail_path,check_id)
},true);
}else{
$('#detail').html('');
}
});
});
},
multiCheckList:function(params){
var self = this;
var checkboxies = this.element.find("[type='checkbox']");
checkboxies.each(function(key,value){
$(this).click(function(){
var check_id = $(this).val();
if($(this).is(':checked')){
dcmgrGUI.notification.publish('checked_box');
//step1:onclick checkbox and generate detail object
self.checked_list[check_id] = {
//+1 is to remove table header
element:$(self.element.find('tr')[key+1]),
c_detail:new DcmgrGUI.Detail({
//id is to search element key
id:check_id,
template_id:params.template_id
})
};
//step2:bind event dcmgrGUI.contentChange
var detail_element = self.checked_list[check_id].c_detail.element;
detail_element.bind('dcmgrGUI.contentChange',function(event,params){
if(self.checked_list[check_id]){
//step4:marge data in template
var data = { item:params.data };
//initialize
if(!params.data){
data.item = self.checked_list[check_id].c_detail.getEmptyData();
}
self.checked_list[check_id].c_detail.filter.execute(data);
if(data.item){
self.detail_filter.execute(data);
$( self.checked_list[check_id].c_detail.template )
.tmpl(data)
.appendTo( $('#detail') );
}
}
});
//step3:update detail
self.checked_list[check_id].c_detail.update({
url:DcmgrGUI.Util.getPagePath(params.detail_path,check_id)
},true);
}else{
dcmgrGUI.notification.publish('unchecked_box');
//remove detail
if(self.checked_list[check_id]){
$($('#detail').find('#'+check_id)).remove();
delete self.checked_list[check_id];
}
}
});
})
}
});
DcmgrGUI.Detail = DcmgrGUI.Class.create(DcmgrGUI.ContentBase, {
});
DcmgrGUI.Refresh = DcmgrGUI.Class.create({
initialize: function(){
this.target = '.refresh';
this.element = $(this.target);
var self = this;
self.element.live('click',function(){
self.element.trigger('dcmgrGUI.refresh');
});
}
});
DcmgrGUI.ItemSelector = DcmgrGUI.Class.create({
initialize: function(params) {
this.element = $(params.target);
this.left_select_id = params.left_select_id;
this.right_select_id = params.right_select_id;
this.data = params.data;
this.leftSelectionsArray = this.emptyArray(this.data.length);
var dataSize = this.data.length;
for(var i = 0;i < dataSize ;i++) {
if (!this.data[i]['selected']) {
var html = '<option id="'+i+'" value="'+ this.data[i]['value'] +'">'+ this.data[i]['name'] +' ('+ this.data[i]['id'] +')</option>';
this.leftSelectionsArray[i] = $(html);
}
}
this.rightSelectionsArray = this.emptyArray(this.data.length);
for(var i = 0;i < dataSize ;i++) {
if (this.data[i]['selected']) {
var html = '<option id="'+i+'" value="'+ this.data[i]['value'] +'">'+ this.data[i]['name'] +' (' + this.data[i]['id'] +')</option>';
this.rightSelectionsArray[i] = $(html);
}
}
this.refreshOptions(this.right_select_id,this.rightSelectionsArray);
this.refreshOptions(this.left_select_id,this.leftSelectionsArray);
},
refreshOptions: function(select_id,selectionsArray){
var selectionsSize = selectionsArray.length;
$(select_id).html('');
for(var i = 0;i < selectionsSize ;i++) {
if(selectionsArray[i] !== null ){
this.element.find(select_id).append(selectionsArray[i]);
}
}
},
emptyArray: function(size) {
var data = [];
for(var i = 0;i < size ;i++) {
data[i] = null;
}
return data;
},
leftToRight: function() {
var self = this;
this.element.find(this.left_select_id).find('option:selected').each(function(){
var index = $(this).attr('id');
self.leftSelectionsArray[index] = null;
self.rightSelectionsArray[index] = this;
$(this).remove();
});
this.refreshOptions(this.right_select_id,this.rightSelectionsArray);
},
rightToLeft: function() {
var self = this;
this.element.find(this.right_select_id).find('option:selected').each(function(){
var index = $(this).attr('id');
self.leftSelectionsArray[index] = this;
self.rightSelectionsArray[index] = null;
$(this).remove();
});
this.refreshOptions(this.left_select_id,this.leftSelectionsArray);
},
getRightSelectionCount: function(){
var count = 0;
$.each(this.rightSelectionsArray,function(key, value){
if(value != null) {
count++;
}
});
return count;
}
});
DcmgrGUI.ToolTip = DcmgrGUI.Class.create({
initialize: function(params) {
this.target = params.target;
this.element = $(params.element);
},
create: function(params){
this.content = this.element.find(this.target)
.cluetip(params);
},
close: function(){
this.content.trigger('hideCluetip');
}
});
DcmgrGUI.Logger = DcmgrGUI.Class.create({
initialize: function() {
this.stack = [];
},
push: function(type, item) {
this.stack.push({
'type': type,
'item': item
});
},
getLog: function(limit, type) {
var size = this.stack.length;
var results = [];
var count = 0;
var limit = limit || this.stack.length;
var type = 'ajaxError';
for(var i=0; i< size; i++) {
if(this.stack[i].type == type) {
if(count < limit) {
results.push(this.stack[i]);
count +=1;
} else {
break;
}
}
}
return results;
}
});
DcmgrGUI.VifMonitorSelector = DcmgrGUI.Class.create({
initialize: function(elem) {
var self = this;
this.enabled = false;
this.index_counter = 0;
this.item_list = [];
this.render_target = elem;
this._findItemAddButton().bind('click', function(e){
// Append new monitoring item selection.
self.addItem();
});
},
monitors: function(){
return this.item_list;
},
_newIndex: function() {
return (this.index_counter++);
},
addItem: function(item_key, json){
var self = this;
var idx = this._newIndex();
var find_unselected_item_key = function(){
var last_key = null;
return _.chain(DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS).keys().find(function(t){
return !_.some(self.item_list, function(j){
return j.item_key === t;
});
}).value();
};
if(item_key === undefined || item_key === null){
item_key = find_unselected_item_key();
}
var new_item = DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS[item_key];
if(new_item === undefined){ throw "Unknown item key: " + item_key; }
// place holder variable for event handlers.
var item_props = {'title': new_item.title,
'item_key': item_key,
'idx': idx,
'json': json,
'row_elem': null
};
this.item_list.push(item_props);
var tr_tag = $('#monitor_selector_tmpl').tmpl({
idx: idx,
itemlist: DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS
});
item_props['row_elem'] = tr_tag;
tr_tag.appendTo(this.render_target);
tr_tag.find('.del_monitor_item').first().bind('click', function(e){
// remove the clicked item from the list.
for(var i in self.item_list) {
if(idx == self.item_list[i].idx){
self.item_list.splice(i, 1);
}
}
item_props.row_elem.remove();
self._refreshSelectItem();
if(DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS_NUM > self.item_list.length){
// enable the plus button again.
self._findItemAddButton().removeAttr("disabled");
}
});
var select_tag = tr_tag.find('.select_monitor_proto').first().bind('change', function(e,json){
var item_key = $(e.currentTarget).val();
var row_item = DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS[item_key];
if(row_item === undefined){
throw "Unknown monitor item: " + item_key;
}
item_props['title']=row_item.title;
item_props['item_key']=item_key;
if(DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS_NUM <= self.item_list.length){
// disable the plus button
self._findItemAddButton().attr("disabled", "disabled");
}
var replace_tgt = $(e.currentTarget).parent().parent().find(".detail_input");
// fill input UI elements for the protocol selected by user.
// Clear current child elements.
replace_tgt.html('');
if( json !== undefined ){
if(json.enabled == true){
$(tr_tag).find('.enabled').attr("checked", "checked");
}else{
$(tr_tag).find('.enabled').removeAttr("checked");
}
// Render option forms for the protocol.
row_item.ui(replace_tgt, json.params);
}else{
// Render option forms for the protocol.
row_item.ui(replace_tgt);
}
self._refreshSelectItem();
});
if( _.isObject(new_item) ){
select_tag.val(item_key).trigger('change', json);
}
},
_refreshSelectItem: function(){
var self = this;
var check_selected_item = function(t){
return _.some(self.item_list, function(i){
return t === i.item_key;
});
};
_.each(this.item_list, function(i) {
var select_tag = $(i.row_elem).find('.select_monitor_proto').first();
select_tag.empty();
_.each(_.keys(DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS), function(k){
var j = DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS[k];
if( k != i.item_key && check_selected_item(k)) {
}else{
select_tag.append("<option value=\""+k+"\">"+j.title+"</option>");
}
});
select_tag.val(i.item_key);
});
},
queryParams: function(){
var res="";
for (var i=0; i < this.item_list.length; i++) {
var itm = this.item_list[i];
var a = ["eth0_monitors["+i+"][title]=" + itm['item_key'],
"eth0_monitors["+i+"][enabled]=" + $(itm['row_elem']).find('.enabled').is(':checked')];
if( itm['json'] !== undefined ){
a.push("eth0_monitors["+i+"][uuid]=" + itm['json'].uuid);
}
if( i > 0 ){ res += '&'; }
res += a.join('&');
var params_query = DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS[itm.item_key].buildQuery(itm['row_elem'], i);
if(!(params_query === undefined || params_query === null)) {
res += "&" + params_query;
}
}
return res;
},
validate: function(){
var err_items = [];
_.each(this.item_list, function(itm){
if(!DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS[itm.item_key].validate(itm['row_elem'])){
err_items.push(itm);
}
});
return (err_items.length == 0);
},
_findItemAddButton: function(){
return $(this.render_target).parent().find('#add_monitor_item');
}
});
DcmgrGUI.VifMonitorSelector.Validator = {
ip_port: function(val){
return /^[0-9]+$/.test(val) && parseInt(val) > 0 && parseInt(val) <= 65535;
},
http_check_path: function(val){
return !/[\\>< ;\"\']/.test(val);
}
};
// constantize the JSON list.
DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS = (function(){
return {
'PING': {
title: 'Ping',
ui: function (elem, params){
},
buildQuery: function(row_elem, idx){
return null;
},
validate: function(row_elem){
return true;
}
},
'HTTP1': {
title: 'HTTP',
ui: function (elem, params){
if(params === undefined) params={port: 80, check_path:"/"};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
elem.append('<br>Path: <input type="text" class="_check_path" width="40" value="'+params['check_path']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val() +
"ð0_monitors["+idx+"][params][check_path]="+$(row_elem).find('._check_path').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val()) &&
DcmgrGUI.VifMonitorSelector.Validator.http_check_path($(row_elem).find('._check_path').val());
}
},
'HTTPS1': {
title: 'HTTPS',
ui: function (elem, params){
if(params === undefined) params={port: 443, check_path:"/"};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
elem.append('<br>Path: <input type="text" class="_check_path" width="40" value="'+params['check_path']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val() +
"ð0_monitors["+idx+"][params][check_path]="+$(row_elem).find('._check_path').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val()) &&
DcmgrGUI.VifMonitorSelector.Validator.http_check_path($(row_elem).find('._check_path').val());
}
},
'FTP': {
title: 'FTP',
ui: function (elem, params){
if(params === undefined) params={port: 21};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val());
}
},
'SSH': {
title: 'SSH',
ui: function (elem, params){
if(params === undefined) params={port: 22};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "ð0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val());
}
},
'SMTP': {
title: 'SMTP',
ui: function (elem, params){
if(params === undefined) params={port: 25};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val());
}
},
'POP3': {
title: 'POP3',
ui: function (elem, params){
if(params === undefined) params={port: 110};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val());
}
},
'IMAP': {
title: 'IMAP',
ui: function (elem, params){
if(params === undefined) params={port: 143};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val());
}
},
'SUBMISSION': {
title: 'Submission',
ui: function (elem, params){
if(params === undefined) params={port: 587};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val());
}
},
'DNS': {
title: 'DNS',
ui: function (elem, params){
if(params === undefined) params={port: 53, query_record: "localhost"};
elem.append('Domain Name: <input type="text" class="_query_record" value="'+params['query_record']+'"></input>');
elem.append('<input type="hidden" class="_udp_port" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]=53ð0_monitors["+idx+"][params][query_record]="+$(row_elem).find('._query_record').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._udp_port').val()) &&
/^[a-zA-z0-9][a-zA-Z0-9\.\-]*$/.test($(row_elem).find('._query_record').val());
}
},
'MYSQL': {
title: 'MySQL',
ui: function (elem, params){
if(params === undefined) params={port: 3306};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val());
}
},
'POSTGRESQL': {
title: 'PostgreSQL',
ui: function (elem, params){
if(params === undefined) params={port: 5432};
elem.append('Port: <input type="text" class="_tcp_port" width="4" value="'+params['port']+'"></input>');
},
buildQuery: function(row_elem, idx){
return "eth0_monitors["+idx+"][params][port]="+$(row_elem).find('._tcp_port').val();
},
validate: function(row_elem){
return DcmgrGUI.VifMonitorSelector.Validator.ip_port($(row_elem).find('._tcp_port').val());
}
}
};
}());
DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS_NUM = (function(){
return _.size(DcmgrGUI.VifMonitorSelector.MONITOR_ITEMS);
}());
DcmgrGUI.prototype = {
initialize:function(){
$.deferred.define();
this.config = {
error_popup: true,
error_popup_once: true
};
this.logger = new DcmgrGUI.Logger();
},
getConfig: function(key){
return this.config[key];
},
setConfig: function(key, value) {
this.config[key] = value;
}
};