Test and icinga.js module setup procedure

Behaviours are now modules and icinga.js automatically
requests module/list (which should be served by the application
and is non static) and retrieves a list of modules to request and
enable.

refs #3753
This commit is contained in:
Jannis Moßhammer 2013-06-14 14:47:31 +02:00 committed by Marius Hein
parent 63f7b8016e
commit 0d0db281f7
4 changed files with 274 additions and 20 deletions

View File

@ -1,27 +1,25 @@
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
define([
'jquery',
'vendor/jquery.sparkline.min',
'logging',
'icinga/behaviour',
'icinga/module',
'icinga/util/async',
'icinga/container',
'modules/list'
], function ($,sparkline,log,behaviour,async,containerMgr, modules) {
], function ($, log, moduleMgr, async, containerMgr, modules) {
'use strict';
/**
* Icinga prototype
*/
var Icinga = function() {
var internalBehaviours = ['icinga/behaviour/actionTable','icinga/behaviour/mainDetail'];
var internalModules = ['icinga/modules/actionTable','icinga/modules/mainDetail'];
this.modules = {};
var failedModules = [];
var initialize = function () {
require(['modules/list']);
enableDefaultBehaviour();
enableInternalModules();
containerMgr.registerAsyncMgr(async);
containerMgr.initializeContainers(document);
@ -30,9 +28,20 @@ define([
enableModules();
};
var enableDefaultBehaviour = function() {
$.each(internalBehaviours,function(idx,behaviourImpl) {
behaviour.enableBehaviour(behaviourImpl,log.error);
var enableInternalModules = function() {
$.each(internalModules,function(idx,module) {
moduleMgr.enableModule(module, log.error);
});
};
var loadModuleScript = function(name) {
moduleMgr.enableModule("modules/"+name, function(error) {
failedModules.push({
name: name,
errorMessage: error
});
});
};
@ -40,17 +49,10 @@ define([
moduleList = moduleList || modules;
$.each(modules,function(idx,module) {
if(module.behaviour) {
behaviour.enableBehaviour(module.name+"/"+module.name,function(error) {
failedModules.push({name: module.name,errorMessage: error});
});
}
loadModuleScript(module.name);
});
};
var enableCb = function(behaviour) {
behaviour.enable();
};
$(document).ready(initialize.bind(this));
@ -60,10 +62,14 @@ define([
*/
loadModule: function(blubb,bla) {
behaviour.registerBehaviour(blubb,bla);
} ,
},
loadIntoContainer: function(ctr) {
},
getFailedModules: function() {
return failedModules;
}
};

View File

@ -0,0 +1,118 @@
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
/**
* ActionTable behaviour as described in
* https://wiki.icinga.org/display/cranberry/Frontend+Components#FrontendComponents-ActionTable
*
* @TODO: Row selection
*/
define(['jquery','logging','icinga/util/async'],function($,log,async) {
"use strict";
var ActionTableBehaviour = function() {
var onTableHeaderClick;
var TABLE_BASE_MATCHER = '.icinga-container table.action';
var linksInActionTable = TABLE_BASE_MATCHER+" tbody tr > a";
var actionTableRow = TABLE_BASE_MATCHER+" tbody tr";
var headerRow = TABLE_BASE_MATCHER+" > th a";
var searchField = ".icinga-container .actiontable.controls input[type=search]";
onTableHeaderClick = function (ev) {
var target = ev.currentTarget,
href = $(target).attr('href'),
destination;
if ($(target).parents('.layout-main-detail').length) {
if ($(target).parents("#icinga-main").length) {
destination = 'icinga-main';
}
else {
destination = 'icinga-detail';
}
} else {
destination = 'icinga-main';
}
async.loadToTarget(destination, href);
ev.preventDefault();
ev.stopImmediatePropagation();
return false;
};
var onLinkTagClick = function(ev) {
var target = ev.currentTarget,
href = $(target).attr('href'),
destination;
if ($(target).parents('.layout-main-detail').length) {
destination = 'icinga-detail';
} else {
destination = 'icinga-main';
}
async.loadToTarget(destination,href);
ev.preventDefault();
ev.stopImmediatePropagation();
return false;
};
var onTableRowClick = function(ev) {
ev.stopImmediatePropagation();
var target = $(ev.currentTarget),
href = target.attr('href'),
destination;
$('tr.active',target.parent('tbody').first()).removeClass("active");
target.addClass('active');
// When the tr has a href, act like it is a link
if(href) {
ev.currentTarget = target.first();
return onLinkTagClick(ev);
}
// Try to find a designated row action
var links = $("a.row-action",target);
if(links.length) {
ev.currentTarget = links.first();
return onLinkTagClick(ev);
}
// otherwise use the first anchor tag
links = $("a",target);
if(links.length) {
ev.currentTarget = links.first();
return onLinkTagClick(ev);
}
log.debug("No target for this table row found");
return false;
};
var onSearchInput = function(ev) {
ev.stopImmediatePropagation();
var txt = $(this).val();
};
this.eventHandler = {};
this.eventHandler[linksInActionTable] = {
'click' : onLinkTagClick
};
this.eventHandler[actionTableRow] = {
'click' : onTableRowClick
};
this.eventHandler[headerRow] = {
'click' : onTableHeaderClick
};
this.eventHandler[searchField] = {
'keyup' : onSearchInput
};
this.enable = function() {
};
};
return new ActionTableBehaviour();
});

View File

@ -0,0 +1,94 @@
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
/**
* Main-Detail layout behaviour as described in
* https://wiki.icinga.org/display/cranberry/Frontend+Components#FrontendComponents-Behaviour
*
*/
define(['jquery','logging','icinga/util/async'],function($,log,async) {
"use strict";
var MainDetailBehaviour = function() {
var onOuterLinkClick = function(ev) {
var a = $(ev.currentTarget),
target = a.attr("target"),
href = a.attr("href");
ev.stopImmediatePropagation();
collapseDetailView();
async.loadToTarget("icinga-main",href);
return false;
};
var onLinkTagClick = function(ev) {
var a = $(ev.currentTarget),
target = a.attr("target"),
href = a.attr("href");
// check for protocol://
if(/^[A-Z]{2,10}\:\/\//i.test(href)) {
window.open(href);
ev.stopImmediatePropagation();
return false;
}
// check for link in table header
if(a.parents('th').length > 0) {
ev.stopImmediatePropagation();
return false;
}
if(typeof target === "undefined") {
if(a.parents("#icinga-detail").length) {
async.loadToTarget("icinga-detail",href);
} else {
async.loadToTarget("icinga-main",href);
}
} else {
switch(target) {
case "main":
async.loadToTarget("icinga-main",href);
collapseDetailView();
break;
case "detail":
async.loadToTarget("icinga-detail",href);
break;
case "popup":
async.loadToTarget(null,href);
break;
default:
return true;
}
}
ev.stopImmediatePropagation();
return false;
};
var expandDetailView = function() {
$("#icinga-detail").parents(".collapsed").removeClass('collapsed');
};
var collapseDetailView = function(elementInDetailView) {
$("#icinga-detail").parents(".layout-main-detail").addClass('collapsed');
};
this.expandDetailView = expandDetailView;
this.collapseDetailView = collapseDetailView;
this.eventHandler = {
'.layout-main-detail * a' : {
'click' : onLinkTagClick
},
'a' : {
'click' : onOuterLinkClick
},
'.layout-main-detail .icinga-container#icinga-detail' : {
'focus' : expandDetailView
}
};
};
return new MainDetailBehaviour();
});

View File

@ -14,7 +14,7 @@ var BASE = "../../../../public/js/";
require(BASE+"icinga/module.js");
var module = rjsmock.getDefine();
GLOBAL.document = $('body');
/**
* Test module that only uses eventhandlers and
* no custom logic
@ -186,5 +186,41 @@ describe('Module loader', function() {
tearDownTestDOM();
$('body').unbind();
});
});
describe('The icinga module bootstrap', function() {
it("Should automatically load all enabled modules", function() {
rjsmock.purgeDependencies();
var testClick = false;
rjsmock.registerDependencies({
"icinga/module": module,
"modules/test" : {
eventHandler: {
"a.test" : {
click : function() {
testClick = true;
}
}
}
},
"icinga/container" : {
registerAsyncMgr: function() {},
initializeContainers: function() {}
},
"modules/list" : [
{ name: 'test' },
{ name: 'test2'} // this one fails
]
});
tearDownTestDOM();
require(BASE+"icinga/icinga.js");
var icinga = rjsmock.getDefine();
$('body').append($("<a class='test'></a>"));
$('a.test').click();
should.equal(testClick, true, "Module wasn't automatically loaded!");
icinga.getFailedModules().should.have.length(1);
should.equal(icinga.getFailedModules()[0].name, "test2");
tearDownTestDOM();
});
});