Improve application configuration

Change-Id: Ic689dee2b15ace091a4e61995d3c64641660b899
This commit is contained in:
Vincent Fournier 2015-07-18 12:51:18 -04:00
parent a97fb551c7
commit c7c793b699
153 changed files with 2300 additions and 2227 deletions

View File

@ -53,6 +53,10 @@ module.exports = function (grunt) {
src: '<%= project.app %>/components/config/config.json',
dest: '<%= project.dist %>/components/config/config.json'
},
{
src: '<%= project.app %>/components/config/componentsConfig.json',
dest: '<%= project.dist %>/components/config/componentsConfig.json'
},
{
src: '<%= project.app %>/components/config/developmentConfig.json',
dest: '<%= project.dist %>/components/config/developmentConfig.json'

View File

@ -10,16 +10,18 @@ angular.module('bansho', [
'bansho.topbar',
'bansho.sidebar',
'bansho.surveil',
'bansho.datasource',
'bansho.directive',
'bansho.host',
'bansho.service',
'bansho.drupal',
'bansho.drupal.tile',
'bansho.drupal.info',
'bansho.view',
'bansho.view.dashboard',
'bansho.view.singleTable',
'bansho.view.page',
'bansho.view.host',
'bansho.view.service',
'bansho.view.config',
'bansho.view.drupalDashboard',
'bansho.view.drupal',
'bansho.grafana'
@ -30,11 +32,13 @@ angular.module('bansho', [
}])
// Reinitialise objects on url change
.run(['$rootScope', 'promisesManager', 'reinitDrupalTiles', 'reinitDrupalInfo',
function ($rootScope, promisesManager, reinitDrupalTiles, reinitDrupalInfo) {
.run(['$rootScope', 'promisesManager', 'sharedData', 'reinitDrupalTiles', 'reinitDrupalInfo', 'componentsConfig',
function ($rootScope, promisesManager, sharedData, reinitDrupalTiles, reinitDrupalInfo, componentsConfig) {
componentsConfig.load();
$rootScope.$on('$locationChangeStart', function () {
reinitDrupalTiles();
reinitDrupalInfo();
promisesManager.clearAllPromises();
sharedData.clear();
});
}]);

View File

@ -54,7 +54,7 @@
@import 'modules-interface/main';
@import '../../components/topbar/topbar';
@import '../../components/sidebar/sidebar';
@import '../../components/tactical/tactical';
@import '../../components/directive/tactical/tactical';
//----------------------------------*\
// TEMPORARY MODULES

View File

@ -11,6 +11,7 @@ angular.module('bansho.authentication', [])
.controller('LoginController', ['$scope', '$rootScope', '$location', 'authService', 'configManager', 'themeManager', function ($scope, $rootScope, $location, authService, configManager, themeManager) {
themeManager.setTheme(themeManager.THEMES.DEFAULT);
$rootScope.isAuthenticated = false;
var login = function (credentials) {
authService.login(credentials);

View File

@ -0,0 +1,252 @@
{
"filters": {
"allHostOpenProblems": {
"name": "Open hosts problems",
"filter": {
"hosts": {
"is": {
"state": [
"DOWN",
"UNREACHABLE"
],
"acknowledged": [
false
]
}
}
}
},
"allHostsProblems": {
"name": "Hosts problems",
"filter": {
"hosts": {
"isnot": {
"state": [
"UP"
]
}
}
}
},
"hostOk": {
"name": "All Ok",
"filter": {
"hosts": {
"is": {
"state": [
"UP"
]
}
}
}
},
"hostNotOk": {
"name": "All not Ok",
"filter": {
"hosts": {
"isnot": {
"state": [
"UP"
]
}
}
}
},
"serviceOk": {
"name": "All Ok",
"filter": {
"services": {
"is": {
"state": [
"OK"
]
}
}
}
},
"serviceNotOk": {
"name": "All not Ok",
"filter": {
"services": {
"isnot": {
"state": [
"OK"
]
}
}
}
},
"allAlert": {
"name": "All ALERT",
"filter": {
"events": {
"is": {
"event_type": [
"ALERT"
]
}
}
}
},
"allNotification": {
"name": "All NOTIFICATION",
"filter": {
"events": {
"is": {
"event_type": [
"NOTIFICATION"
]
}
}
}
},
"allOk": {
"name": "All OK",
"filter": {
"hosts": {
"is": {
"state": [
"UP"
]
}
},
"services": {
"is": {
"state": [
"OK"
]
}
}
}
},
"allNotOk": {
"name": "All not OK",
"filter": {
"hosts": {
"isnot": {
"state": [
"UP"
]
}
},
"services": {
"isnot": {
"state": [
"OK"
]
}
}
}
},
"allServices": {
"name": "All",
"filter": {
"hosts": {},
"services": {}
}
},
"allServicesProblems": {
"name": "Open services problems",
"filter": {
"services": {
"isnot": {
"state": [
"OK"
]
}
}
}
},
"allServiceOpenProblems": {
"name": "Open services problems",
"filter": {
"services": {
"isnot": {
"state": [
"OK"
]
},
"is": {
"acknowledged": [
false
]
}
}
}
},
"allServiceOpenProblemsOnly": {
"name": "Open services problems",
"filter": {
"services": {
"isnot": {
"state": [
"OK"
]
},
"is": {
"acknowledged": [
false
]
}
},
"hosts": {
"is": {
"state": [
"UP"
]
}
}
}
},
"all": {
"name": "All",
"filter": {
"services": {},
"hosts": {},
"events": {}
}
}
},
"inputSource": {
"hostOpenProblems": {
"provider": "status",
"endpoint": "hosts",
"filter": "allHostOpenProblems"
},
"serviceOpenProblems": {
"provider": "status",
"endpoint": "services",
"filter": "allServiceOpenProblems"
},
"serviceOpenProblemsOnly": {
"provider": "status",
"endpoint": "services",
"filter": "allServiceOpenProblemsOnly"
},
"hostsProblems": {
"provider": "status",
"endpoint": "hosts",
"filter": "allHostsProblems"
},
"servicesProblems": {
"provider": "status",
"endpoint": "services",
"filter": "allServicesProblems"
},
"events": {
"provider": "status",
"endpoint": "events",
"filter": "all"
},
"hosts": {
"provider": "status",
"endpoint": "hosts",
"filter": "all"
},
"services": {
"provider": "status",
"endpoint": "services",
"filter": "all"
}
}
}

View File

@ -44,7 +44,50 @@ angular.module('bansho.config', [])
};
}])
.service('configManager', ['$http', '$q', function ($http, $q) {
.service('componentsConfig', ['$http', function($http) {
var componentsConfig;
this.getFilter = function (name) {
return componentsConfig.filters[name];
};
this.mergeFilters = function (filters) {
var filter = {};
angular.forEach(filters, function (f) {
angular.forEach(f, function (endpointFilter, endpoint) {
if (!filter[endpoint]) {
filter[endpoint] = {};
}
angular.forEach(endpointFilter, function (constraint, constraintType) {
if (!filter[endpoint][constraintType]) {
filter[endpoint][constraintType] = {};
}
angular.forEach(constraint, function (value, key) {
filter[endpoint][constraintType][key] = value;
});
});
});
});
return filter;
};
this.getInputSource = function (name) {
return componentsConfig.inputSource[name];
};
this.load = function () {
$http.get('components/config/componentsConfig.json')
.success(function(config) {
componentsConfig = config;
});
};
}])
.service('configManager', ['$http', '$q', 'componentsConfig', function ($http, $q, componentsConfig) {
var config = {},
developmentConfig = {};
@ -112,10 +155,11 @@ angular.module('bansho.config', [])
this.fetchConfig = function (useStoredConfig) {
var responsePromise = $q.defer();
componentsConfig.load();
$http.get('surveil/v2/bansho/config')
.success(function (conf) {
if (!useStoredConfig || jQuery.isEmptyObject(conf)) {
$http.get('components/config/config.json')
.success(function (conf) {
config.data = conf;

View File

@ -3,46 +3,105 @@
"theme": "dark"
},
"dashboardConfig": {
"title": "Unhandled service problems",
"refreshInterval": 30,
"template": "dashboard",
"template": "page",
"attributes": {
"refreshInterval": 30
},
"components": [
{
"type": "actionbar",
"config": {
"components": [
"filter",
"acknowledge",
"downtime",
"recheck",
"more",
"search-filter"
],
"tableId": [
0,
1,
2,
3
]
}
}
],
"extra_components": [
{
"type": "tactical",
"config": {
"attributes": {
"title": "Tactical Overview",
"components": {
"statusOverview": true,
"currentHealth": true,
"topAlertProducers": false
}
},
{
"type": "tabpanel",
"attributes": {
"navigation": [
{
"title": "Open Problems",
"panelId": "openProblems",
"provider": "nbServicesHostsOpenProblems"
},
{
"title": "All Problems",
"panelId": "allProblems",
"provider": "nbServicesHostsOpenProblemsDoubleCount"
}
]
},
"components": [
{
"type": "panel",
"attributes": {
"panelId": "openProblems"
},
"components": [
{
"type": "actionbar",
"attributes": {
"tableId": [
0,
1
]
},
"components": [
{
"type": "actionbar-filter",
"attributes": {
"filters": [
{
"location": "componentsConfig",
"content": "all"
},
{
"location": "componentsConfig",
"content": "allOk"
},
{
"location": "componentsConfig",
"content": "allNotOk"
}
]
}
},
{
"type": "actionbar-acknowledge",
"attributes": {}
},
{
"type": "actionbar-downtime",
"attributes": {}
},
{
"type": "actionbar-recheck",
"attributes": {}
},
{
"type": "actionbar-more",
"attributes": {}
},
{
"type": "actionbar-search-filter",
"attributes": {}
}
]
},
{
"type": "title",
"attributes": {
"title": "Open hosts problems",
"item": "host",
"provider": "nbHostsOpenProblems"
}
},
{
"type": "table",
"config": {
"title": "Open Hosts problems",
"attributes": {
"tableId": 0,
"cells": {
"text": [
"Host",
@ -60,32 +119,24 @@
]
},
"headerFollow": false,
"inputSource": {
"service": "surveilStatus",
"config": {
"apiName": "hosts",
"filters": {
"is": {
"acknowledged": [
false
],
"state": [
"DOWN",
"UNREACHABLE"
]
}
}
}
},
"inputSource": "hostOpenProblems",
"isWrappable": false,
"checkColumn": true,
"noRepeatCell": ""
}
},
{
"type": "title",
"attributes": {
"title": "Open Service Problems",
"item": "service",
"provider": "nbServicesOpenProblemsOnly"
}
},
{
"type": "table",
"config": {
"title": "Open Service problems",
"attributes": {
"tableId": 1,
"cells": {
"text": [
"Host",
@ -101,44 +152,90 @@
]
},
"headerFollow": false,
"inputSource": {
"service": "surveilStatus",
"config": {
"apiName": "services",
"filters": {
"isnot": {
"state": [
"OK"
],
"host_state": [
"DOWN",
"UNREACHABLE"
]
},
"is": {
"acknowledged": [
false
]
}
}
}
},
"inputSource": "serviceOpenProblemsOnly",
"isWrappable": true,
"checkColumn": true,
"noRepeatCell": "host"
}
}
]
},
{
"type": "table",
"config": {
"type": "panel",
"attributes": {
"panelId": "allProblems",
"provider": "nbServicesHostsOpenProblems"
},
"components": [
{
"type": "actionbar",
"attributes": {
"tableId": [
2,
3
]
},
"components": [
{
"type": "actionbar-filter",
"attributes": {
"filters": [
{
"location": "componentsConfig",
"content": "all"
},
{
"location": "componentsConfig",
"content": "allOk"
},
{
"location": "componentsConfig",
"content": "allNotOk"
}
]
}
},
{
"type": "actionbar-acknowledge",
"attributes": {}
},
{
"type": "actionbar-downtime",
"attributes": {}
},
{
"type": "actionbar-recheck",
"attributes": {}
},
{
"type": "actionbar-more",
"attributes": {}
},
{
"type": "actionbar-search-filter",
"attributes": {}
}
]
},
{
"type": "title",
"attributes": {
"title": "Hosts problems",
"item": "host",
"provider": "nbHostsOpenProblems"
}
},
{
"type": "table",
"attributes": {
"tableId": 2,
"cells": {
"text": [
"Host",
"Address",
"Duration",
"Last check",
"Host status"
"Lastcheck",
"Hoststatus"
],
"name": [
"status_host",
@ -149,28 +246,24 @@
]
},
"headerFollow": false,
"inputSource": {
"service": "surveilStatus",
"config": {
"apiName": "hosts",
"filters": {
"isnot": {
"state": [
"UP"
]
}
}
}
},
"inputSource": "hostsProblems",
"isWrappable": false,
"checkColumn": true,
"noRepeatCell": ""
}
},
{
"type": "table",
"config": {
"type": "title",
"attributes": {
"title": "Services problems",
"item": "service",
"provider": "nbServicesOpenProblems"
}
},
{
"type": "table",
"attributes": {
"tableId": 3,
"cells": {
"text": [
"Host",
@ -186,50 +279,84 @@
]
},
"headerFollow": false,
"inputSource": {
"service": "surveilStatus",
"config": {
"apiName": "services",
"filters": {
"isnot": {
"state": [
"OK"
]
}
}
}
},
"inputSource": "servicesProblems",
"isWrappable": true,
"checkColumn": true,
"noRepeatCell": "host"
}
}
]
}
]
}
]
},
"liveHosts": {
"title": "Hosts",
"refreshInterval": 30,
"template": "tables",
"template": "page",
"components": [
{
"type": "actionbar",
"config": {
"type": "panel",
"components": [
"filter",
"acknowledge",
"downtime",
"recheck",
"more",
"search-filter"
],
"tableId": [0]
{
"type": "title",
"attributes": {
"title": "Hosts"
}
},
{
"type": "actionbar",
"attributes": {
"tableId": [
0
]
},
"components": [
{
"type": "actionbar-filter",
"attributes": {
"filters": [
{
"location": "componentsConfig",
"content": "all"
},
{
"location": "componentsConfig",
"content": "hostOk"
},
{
"location": "componentsConfig",
"content": "hostNotOk"
}
]
}
},
{
"type": "actionbar-acknowledge",
"attributes": {}
},
{
"type": "actionbar-downtime",
"attributes": {}
},
{
"type": "actionbar-recheck",
"attributes": {}
},
{
"type": "actionbar-more",
"attributes": {}
},
{
"type": "actionbar-search-filter",
"attributes": {}
}
]
},
{
"type": "table",
"config": {
"title": "Hosts",
"attributes": {
"tableId": 0,
"refreshInterval": 30,
"cells": {
"text": [
"Host",
@ -247,45 +374,82 @@
]
},
"headerFollow": true,
"inputSource": {
"service": "surveilStatus",
"config": {
"apiName": "hosts",
"filters": {}
}
},
"inputSource": "hosts",
"isWrappable": false,
"noRepeatCell": "",
"checkColumn": true,
"containsActionBar": true
"checkColumn": true
}
}
]
}
]
},
"liveServices": {
"title": "Services",
"refreshInterval": 30,
"template": "tables",
"template": "page",
"components": [
{
"type": "actionbar",
"config": {
"type": "panel",
"components": [
"filter",
"acknowledge",
"downtime",
"recheck",
"more",
"search-filter"
],
"tableId": [0]
{
"type": "title",
"attributes": {
"title": "Services"
}
},
{
"type": "actionbar",
"attributes": {
"tableId": [
0
]
},
"components": [
{
"type": "actionbar-filter",
"attributes": {
"filters": [
{
"location": "componentsConfig",
"content": "all"
},
{
"location": "componentsConfig",
"content": "serviceOk"
},
{
"location": "componentsConfig",
"content": "serviceNotOk"
}
]
}
},
{
"type": "actionbar-acknowledge",
"attributes": {}
},
{
"type": "actionbar-downtime",
"attributes": {}
},
{
"type": "actionbar-recheck",
"attributes": {}
},
{
"type": "actionbar-more",
"attributes": {}
},
{
"type": "actionbar-search-filter",
"attributes": {}
}
]
},
{
"type": "table",
"config": {
"title": "Services",
"attributes": {
"tableId": 0,
"refreshInterval": 30,
"cells": {
"text": [
"Host",
@ -300,48 +464,76 @@
"status_last_check"
]
},
"inputSource": {
"service": "surveilStatus",
"config": {
"apiName": "services",
"filters": {}
}
},
"isWrappable": false,
"noRepeatCell": "host",
"headerFollow": true,
"containsActionBar": true,
"checkColumn": true
"inputSource": "services",
"isWrappable": false,
"checkColumn": true,
"noRepeatCell": "host"
}
}
]
}
]
},
"liveEvents": {
"title": "Events",
"refreshInterval": 30,
"template": "tables",
"template": "page",
"components": [
{
"type": "actionbar",
"config": {
"type": "panel",
"components": [
"filter",
"more",
"search-filter"
],
"tableId": [0]
{
"type": "title",
"attributes": {
"title": "Events"
}
},
{
"type": "actionbar",
"attributes": {
"tableId": [
0
]
},
"components": [
{
"type": "actionbar-filter",
"attributes": {
"filters": [
{
"location": "componentsConfig",
"content": "all"
},
{
"location": "componentsConfig",
"content": "allAlert"
},
{
"location": "componentsConfig",
"content": "allNotification"
}
]
}
},
{
"type": "actionbar-more",
"attributes": {}
},
{
"type": "actionbar-search-filter",
"attributes": {}
}
]
},
{
"type": "table",
"config": {
"title": "Hosts",
"attributes": {
"refreshInterval": 30,
"tableId": 0,
"cells": {
"text": [
"Event type",
"Output",
"Host name",
"Hostname",
"Service",
"Time",
"Complete data"
@ -356,30 +548,86 @@
]
},
"headerFollow": true,
"inputSource": {
"service": "surveilStatus",
"config": {
"apiName": "events",
"filters": {}
}
},
"inputSource": "events",
"isWrappable": false,
"noRepeatCell": "",
"checkColumn": false,
"containsActionBar": false
"noRepeatCell": ""
}
}
]
}
]
},
"host": {
"title": "Host",
"refreshInterval": 30,
"template": "host"
"template": "host",
"components": [
{
"type": "panel",
"components": [
{
"type": "host",
"components": [
{
"type": "host-main",
"attributes": {}
},
{
"type": "host-live",
"attributes": {}
},
{
"type": "host-load",
"attributes": {}
},
{
"type": "host-cpu",
"attributes": {}
},
{
"type": "host-info",
"attributes": {}
},
{
"type": "host-services-list",
"attributes": {}
}
]
}
]
}
]
},
"service": {
"title": "Service",
"refreshInterval": 30,
"template": "service"
"template": "service",
"components": [
{
"type": "panel",
"components": [
{
"type": "service",
"components": [
{
"type": "service-main",
"attributes": {}
},
{
"type": "service-live",
"attributes": {}
},
{
"type": "service-info",
"attributes": {}
},
{
"type": "service-graphs",
"attributes": {}
}
]
}
]
}
],
"refreshInterval": 30
},
"drupal": {
"title": "Drupal",

View File

@ -0,0 +1,193 @@
'use strict';
angular.module('bansho.datasource', ['bansho.surveil'])
.value('tableGlobalConfig', {'cellToFieldsMap': {}, 'cellWrappableField': {}})
.service('datasource', ['$filter', 'surveilStatus', 'surveilQuery', 'componentsConfig', 'tableGlobalConfig',
function ($filter, surveilStatus, surveilQuery, componentsConfig, tableGlobalConfig) {
var providerServices = {
status: surveilStatus
},
config = [],
data = [],
filteredData = [],
listeners = [];
function notifyDataChanged(tableId) {
angular.forEach(listeners[tableId], function (callback) {
callback(filteredData[tableId], config[tableId].isCheckAll);
});
}
function filterData(tableId) {
filteredData[tableId] = $filter('filter')(data[tableId], config[tableId].searchFilter);
notifyDataChanged(tableId);
}
function refreshTableData(tableId) {
var conf = config[tableId],
inputSource = componentsConfig.getInputSource(conf.inputSource),
filter = componentsConfig.getFilter(inputSource.filter).filter,
promise;
if (config[tableId].queryFilter) {
filter = componentsConfig.mergeFilters([config[tableId].queryFilter, filter]);
}
promise = providerServices[inputSource.provider].getData([], filter, inputSource.endpoint);
promise.then(function (newData) {
data[tableId] = newData;
config[tableId].isCheckAll = false;
filterData(tableId);
}, function (error) {
throw new Error('getTableData : Query failed' + error);
});
}
return {
refreshTableData: refreshTableData,
addTable: function (tableId, conf) {
config[tableId] = conf;
config[tableId].requestFields = [];
angular.forEach(config[tableId].cells.name, function (cell) {
angular.forEach(tableGlobalConfig.cellToFieldsMap[cell], function (_value) {
config[tableId].requestFields.push(_value);
});
});
},
getConfig: function (tableId) {
return config[tableId];
},
forEachCheckedEntry: function (tableId, callbackIsChecked) {
angular.forEach(filteredData[tableId], function (entry) {
if (entry.is_checked) {
callbackIsChecked(entry);
}
});
notifyDataChanged(tableId);
},
registerDataChanged: function (tableId, callback) {
if (!listeners[tableId]) {
listeners[tableId] = [];
}
listeners[tableId].push(callback);
},
setAllCheckTable: function (tableId, isChecked) {
config[tableId].isCheckAll = isChecked;
angular.forEach(filteredData[tableId], function (entry) {
entry.is_checked = isChecked;
});
notifyDataChanged(tableId, isChecked);
},
setSearchFilter: function (tableId, searchFilter) {
config[tableId].searchFilter = searchFilter;
filterData(tableId);
notifyDataChanged(tableId);
},
setQueryFilter: function (tableId, queryFilter) {
config[tableId].queryFilter = queryFilter;
refreshTableData(tableId);
}
};
}])
.service('sharedData', ['$interval', 'surveilStatus',
function ($interval, surveilStatus) {
var sharedData = {},
listeners = {},
providers = {
'nbHostsOpenProblems': function (key) {
surveilStatus.getNbHostOpenProblems().then(function (nbHostProblems) {
sharedData[key].value = nbHostProblems;
notifyListeners(key);
});
},
'nbServicesOpenProblems': function (key) {
surveilStatus.getNbServiceOpenProblems().then(function (nbServiceProblems) {
sharedData[key].value = nbServiceProblems;
notifyListeners(key);
});
},
'nbHosts': function (key) {
surveilStatus.getNbHosts().then(function (nbHosts) {
sharedData[key].value = nbHosts;
notifyListeners(key);
});
},
'nbServices': function (key) {
surveilStatus.getNbServices().then(function (nbServices) {
sharedData[key].value = nbServices;
notifyListeners(key);
});
},
'nbServicesOpenProblemsOnly': function (key) {
surveilStatus.getNbServiceOpenProblemsOnly().then(function (nbServices) {
sharedData[key].value = nbServices;
notifyListeners(key);
});
},
'nbServicesHostsOpenProblems': function (key) {
surveilStatus.getNbHostsProblems().then(function (nbHosts) {
surveilStatus.getNbServiceOpenProblemsOnly().then(function (nbServices) {
sharedData[key].value = nbHosts + nbServices;
notifyListeners(key);
});
});
},
'nbServicesHostsOpenProblemsDoubleCount': function (key) {
surveilStatus.getNbHostsProblems().then(function (nbHosts) {
surveilStatus.getNbServiceOpenProblems().then(function (nbServices) {
sharedData[key].value = nbHosts + nbServices;
notifyListeners(key);
});
});
}
};
var notifyListeners = function (key) {
angular.forEach(listeners[key], function (onChange) {
onChange(sharedData[key].value);
});
};
return {
clear: function () {
angular.forEach(sharedData, function (provider) {
$interval.cancel(provider.promise);
});
sharedData = {};
listeners = {};
},
getData: function (key, interval, onChange) {
if (!sharedData[key]) {
sharedData[key] = {
interval: interval
};
listeners[key] = [
onChange
];
providers[key](key);
$interval(providers[key](key), interval);
} else {
listeners[key].push(onChange);
if (sharedData[key].interval >= interval) {
sharedData[key].interval = interval;
$interval.cancel(sharedData[key].promise);
sharedData[key].promise = $interval(providers[key](key), interval);
}
}
return sharedData[key].value;
}
};
}]);

View File

@ -1,4 +1,5 @@
<menu class="filters">
<ul class="filters__list clearfix">
<bansho-components components="components"></bansho-components>
</ul>
</menu>

View File

@ -0,0 +1,22 @@
'use strict';
angular.module('bansho.actionbar', ['bansho.datasource', 'bansho.surveil', 'bansho.notifications'])
.directive('banshoActionbar', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
options: '='
},
templateUrl: 'components/directive/actionbar/actionbar.html',
link: function (scope, element) {
scope.tableId = scope.options.attributes.tableId;
scope.components = scope.options.components;
angular.forEach(scope.components, function (component) {
component.attributes.tableId = scope.tableId;
});
$compile(element.contents())(scope);
}
};
}]);

View File

@ -1,38 +1,32 @@
'use strict';
angular.module('bansho.table.actionbar')
angular.module('bansho.actionbar')
.directive('banshoActionbarAcknowledge', [function () {
return {
restrict: 'E',
templateUrl: 'components/table/actionbar/component_acknowledge/acknowledge.html',
templateUrl: 'components/directive/actionbar/component_acknowledge/acknowledge.html',
scope: {
tableId: '='
options: '='
},
controller: ['$scope', 'tables', 'surveilActions', 'notifications',
function ($scope, tables, surveilActions, notifications) {
controller: ['$scope', 'datasource', 'surveilActions', 'notifications',
function ($scope, datasource, surveilActions, notifications) {
$scope.isAcknowledgeFormShown = false;
$scope.switchAcknowledgeFormShown = function () {
$scope.isAcknowledgeFormShown = !$scope.isAcknowledgeFormShown;
};
$scope.acknowledgeProblems = function () {
angular.forEach($scope.tableId, function (tableId) {
tables.forEachCheckedEntry(tableId, function (entry) {
var service_description;
if ('description' in entry) {
service_description = entry.description;
}
surveilActions.acknowledge(entry.host_name, service_description, $scope.attrs).then(function (data) {
notifications.push('success', 'Acknowledgement', 'Acknowledged ' + entry.host_name);
angular.forEach($scope.options.attributes.tableId, function (tableId) {
datasource.forEachCheckedEntry(tableId, function (entry) {
surveilActions.acknowledge(entry.host_host_name, entry.service_service_description, $scope.attrs).then(function (data) {
notifications.push('success', 'Acknowledgement', 'Acknowledged ' + entry.host_host_name + ' ' + entry.service_service_description);
},
function (error) {
notifications.push('error', 'Acknowledgement', 'Could not acknowledge ' + entry.host_name);
notifications.push('error', 'Acknowledgement', 'Could not acknowledge ' + entry.host_host_name + ' ' + entry.service_service_description);
});
});
tables.setAllCheckTable(tableId, false);
datasource.setAllCheckTable(tableId, false);
});
$scope.isAcknowledgeFormShown = false;

View File

@ -0,0 +1,39 @@
'use strict';
angular.module('bansho.actionbar')
.directive('banshoActionbarDowntime', [function () {
return {
restrict: 'E',
templateUrl: 'components/directive/actionbar/component_downtime/downtime.html',
scope: {
options: '='
},
controller: ['$scope', 'datasource', 'surveilActions', 'notifications',
function ($scope, datasource, surveilActions, notifications) {
$scope.tableId = $scope.options.attributes.tableId;
$scope.isDowntimeFormShown = false;
$scope.switchDowntimeFormShown = function () {
$scope.isDowntimeFormShown = !$scope.isDowntimeFormShown;
};
$scope.sendDowntime = function () {
angular.forEach($scope.options.attributes.tableId, function (tableId) {
datasource.forEachCheckedEntry(tableId, function (entry) {
surveilActions.downtime(entry.host_host_name, entry.service_service_description, $scope.attrs).then(function (data) {
notifications.push('success', 'Downtime', 'Added downtime for ' + entry.host_host_name + ' ' + entry.service_service_description);
},
function (error) {
notifications.push('error', 'Downtime', 'Could not add downtime for ' + entry.host_host_name + ' ' + entry.service_service_description);
});
});
datasource.setAllCheckTable(tableId, false);
});
$scope.isDowntimeFormShown = false;
};
}
]
};
}]);

View File

@ -1,19 +1,19 @@
<li class="filters__item filters__item--more clearfix">
<li class="filters__item filters__item--problems">
<button class="filters__button"
type="button"
data-toggle="collapse"
data-target="#filtersProblems"
aria-expanded="false"
aria-controls="filtersProblems">
<span>{{activeFilter.text}}</span>
aria-controls="filtersProblems"
data-ng-click="switchFilterFormShown()">
<span>{{activeFilter.name}}</span>
<i class="ico-down-dir"></i>
</button>
<div class="filters__panel collapse" id="filtersProblems">
<div class="filters__panel collapse" ng-class="{collapse: isShown}" id="filtersProblems">
<ul class="filters__sublist">
<li class="filters__subitem" ng-repeat="actionbarFilter in possibleFilters" ng-click="activateFilter($index)">
<a class="filters__link state--current" ng-if="actionbarFilter === activeFilter">{{actionbarFilter.text}}</a>
<a class="filters__link" ng-if="actionbarFilter !== activeFilter">{{actionbarFilter.text}}</a>
<li class="filters__subitem" ng-repeat="actionbarFilter in filters" ng-click="activateFilter($index)">
<a class="filters__link state--current" ng-if="actionbarFilter === activeFilter">{{actionbarFilter.name}}</a>
<a class="filters__link" ng-if="actionbarFilter !== activeFilter">{{actionbarFilter.name}}</a>
</li>
</ul>
</div>

View File

@ -0,0 +1,49 @@
'use strict';
angular.module('bansho.actionbar')
.directive('banshoActionbarFilter', ['componentsConfig', function (componentsConfig) {
return {
restrict: 'E',
scope: {
options: '='
},
templateUrl: 'components/directive/actionbar/component_filter/filter.html',
controller: ['$scope', 'datasource', function ($scope, datasource) {
$scope.tableId = $scope.options.attributes.tableId;
$scope.filters = [];
angular.forEach($scope.options.attributes.filters, function (filter) {
switch (filter.location) {
case 'inline':
$scope.filters.push(filter.content);
break;
case 'componentsConfig':
$scope.filters.push(
componentsConfig.getFilter(
filter.content
)
);
break;
}
});
$scope.isShown = false;
$scope.activeFilter = $scope.filters[0];
$scope.components = $scope.options.components;
$scope.switchFilterFormShown = function () {
$scope.isShown = !$scope.isShown;
};
$scope.activateFilter = function (item) {
$scope.activeFilter = $scope.filters[item];
angular.forEach($scope.tableId, function (tableId) {
datasource.setQueryFilter(tableId, $scope.activeFilter.filter);
});
$scope.isShown = false;
};
}]
};
}]);

View File

@ -0,0 +1,13 @@
'use strict';
angular.module('bansho.actionbar')
.directive('banshoActionbarMore', [function () {
return {
restrict: 'E',
scope: {
'tableId': '='
},
templateUrl: 'components/directive/actionbar/component_more/more.html',
controller: ['$scope', 'datasource', function ($scope, datasource) {}]
};
}]);

View File

@ -0,0 +1,30 @@
'use strict';
angular.module('bansho.actionbar')
.directive('banshoActionbarRecheck', [function () {
return {
restrict: 'EA',
scope: {
options: '='
},
templateUrl: 'components/directive/actionbar/component_recheck/recheck.html',
controller: ['$scope', 'datasource', 'surveilActions', 'notifications',
function ($scope, datasource, surveilActions, notifications) {
$scope.sendRecheck = function () {
angular.forEach($scope.options.attributes.tableId, function (tableId) {
datasource.forEachCheckedEntry(tableId, function (entry) {
surveilActions.recheck(entry.host_host_name, entry.service_service_description).then(function (data) {
notifications.push('success', 'Recheck', 'Scheduled recheck for ' + entry.host_host_name + ' ' + entry.service_service_description);
},
function (error) {
notifications.push('error', 'Recheck', 'Could not schedule recheck for ' + entry.host_host_name + ' ' + entry.service_service_description);
});
});
datasource.setAllCheckTable(tableId, false);
});
};
}
]
};
}]);

View File

@ -0,0 +1,19 @@
'use strict';
angular.module('bansho.actionbar')
.directive('banshoActionbarSearchFilter', [function () {
return {
restrict: 'E',
scope: {
options: '='
},
templateUrl: 'components/directive/actionbar/component_search_filter/search_filter.html',
controller: ['$scope', 'datasource', function ($scope, datasource) {
$scope.searchFilterChange = function () {
angular.forEach($scope.options.attributes.tableId, function (tableId) {
datasource.setSearchFilter(tableId, $scope.searchFilter);
});
};
}]
};
}]);

View File

@ -0,0 +1,11 @@
'use strict';
angular.module('bansho.directive', [
'bansho.actionbar',
'bansho.host',
'bansho.service',
'bansho.table',
'bansho.tabpanel',
'bansho.tactical',
'bansho.title'
]);

View File

@ -0,0 +1,6 @@
<article>
<section class="main__content tabpanel">
<bansho-components components="components"></bansho-components>
</section>
</article>

View File

@ -0,0 +1,37 @@
'use strict';
angular.module('bansho.host', ['bansho.datasource'])
.directive('banshoHost', function () {
return {
restrict: 'E',
scope: {
options: '='
},
templateUrl: 'components/directive/host/host.html',
controller: ['$scope', 'pageParams', 'surveilStatus', 'iframeUrl',
function ($scope, pageParams, surveilStatus, iframeUrl) {
var hostname = pageParams.hostname;
$scope.param = {};
surveilStatus.getHost(hostname).then(function (data) {
surveilStatus.getService(hostname).then(function(services) {
$scope.param.host = data[0];
$scope.param.host.services = [];
angular.forEach(services, function (service) {
if (service.service_description === 'cpu') {
$scope.param.host.cpu = service;
} else if (service.service_description === 'load') {
$scope.param.host.load = service;
$scope.param.host.load.iframeUrl = iframeUrl.getIFrameUrl("metric_load1", hostname, "load");
} else {
$scope.param.host.services.push(service);
}
});
});
});
$scope.components = $scope.options.components;
}]
};
});

View File

@ -0,0 +1,15 @@
<div data-ng-show="param.host.cpu" class="subcomponent__live subcomponent__small">
<h2>Cpu</h2>
<table class="data-table">
<tbody>
<tr>
<td>State</td>
<td><bansho-service-state-icon state="param.host.cpu.state"></bansho-service-state-icon> {{param.host.cpu.state}}</td>
</tr>
<tr>
<td>Output</td>
<td>{{param.host.cpu.plugin_output}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,12 @@
'use strict';
angular.module('bansho.host')
.directive('banshoHostCpu', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/host/host_cpu/host_cpu.html',
link: function (scope) {
scope.param = scope.$parent.param;
}
};
});

View File

@ -0,0 +1,35 @@
<div class="subcomponent__live">
<h2>Info</h2>
<table class="data-table">
<tbody>
<tr>
<td>Last check</td>
<td>{{param.host.host_last_check | timeElapsed}}</td>
</tr>
<tr>
<td>Check period</td>
<td>{{param.host.config_host_check_period}}</td>
</tr>
<tr>
<td>Notification period</td>
<td>{{param.host.config_host_notification_period}}</td>
</tr>
<tr>
<td>Active checks</td>
<td>{{param.host.config_host_active_checks}}</td>
</tr>
<tr>
<td>Notifications</td>
<td>{{param.host.config_host_notifications_enabled}}</td>
</tr>
<tr>
<td>Event Handler</td>
<td>{{param.host.config_host_event_handler_enabled}}</td>
</tr>
<tr>
<td>Flag detection</td>
<td>{{param.host.config_host_flap_detection_enabled}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,12 @@
'use strict';
angular.module('bansho.host')
.directive('banshoHostInfo', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/host/host_info/host_info.html',
link: function (scope) {
scope.param = scope.$parent.param;
}
};
});

View File

@ -0,0 +1,15 @@
<div class="subcomponent__live subcomponent__small">
<h2>Live status</h2>
<table class="data-table">
<tbody>
<tr>
<td>State</td>
<td><bansho-host-state-icon state="param.host.host_state"></bansho-host-state-icon> {{param.host.host_state}}</td>
</tr>
<tr>
<td>Output</td>
<td>{{param.host.host_plugin_output}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,12 @@
'use strict';
angular.module('bansho.host')
.directive('banshoHostLive', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/host/host_live/host_live.html',
link: function (scope) {
scope.param = scope.$parent.param;
}
};
});

View File

@ -0,0 +1,16 @@
<div data-ng-show="param.host.load" class="subcomponent__live subcomponent__small">
<h2>Load</h2>
<iframe src="{{param.host.load.iframeUrl}}" width="450" height="200" frameborder="0"></iframe>
<table class="data-table">
<tbody>
<tr>
<td>State</td>
<td><bansho-service-state-icon state="param.host.load.state"></bansho-service-state-icon> {{param.host.load.state}}</td>
</tr>
<tr>
<td>Output</td>
<td>{{param.host.load.plugin_output}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,12 @@
'use strict';
angular.module('bansho.host')
.directive('banshoHostLoad', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/host/host_load/host_load.html',
link: function (scope) {
scope.param = scope.$parent.param;
}
};
});

View File

@ -0,0 +1,9 @@
<div class="subcomponent__live subcomponent__title">
<header class="main__content__header clearfix">
<h2 class="main__content__title">
{{param.host.host_host_name}}
<span class="subtitle" ng-show="param.host.host_config_alias">(param.host.host_config_alias)</span>
<span class="subtitle">{{param.host.host_address}}</span>
</h2>
</header>
</div>

View File

@ -0,0 +1,12 @@
'use strict';
angular.module('bansho.host')
.directive('banshoHostMain', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/host/host_main/host_main.html',
link: function (scope) {
scope.param = scope.$parent.param;
}
};
});

View File

@ -0,0 +1,19 @@
<div ng-show="param.host.services.length >= 1" class="subcomponent__live">
<h2>Services</h2>
<table class="data-table">
<thead>
<tr>
<th>Service description</th>
<th>Acknowledged</th>
<th>State</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="service in param.host.services">
<td><a href="#/view?view=service&host_name={{service.service_host_name}}&description={{service.service_service_description}}">{{service.service_service_description}}</a>
<td>{{service.service_acknowledged ? "Yes" : "No"}}</td>
<td><bansho-service-state-icon state="service.service_state"></bansho-service-state-icon>{{service.service_state}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,12 @@
'use strict';
angular.module('bansho.host')
.directive('banshoHostServicesList', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/host/host_services_list/host_services_list.html',
link: function (scope) {
scope.param = scope.$parent.param;
}
};
});

View File

@ -0,0 +1,5 @@
<article>
<section class="main__content tabpanel">
<bansho-components components="components"></bansho-components>
</section>
</article>

View File

@ -0,0 +1,32 @@
'use strict';
angular.module('bansho.service', ['bansho.datasource'])
.directive('banshoService', function () {
return {
restrict: 'E',
scope: {
options: '='
},
templateUrl: 'components/directive/service/service.html',
controller: ['$scope', 'pageParams', 'surveilStatus', 'iframeUrl',
function ($scope, pageParams, surveilStatus, iframeUrl) {
var hostname = pageParams.host_name,
serviceDescription = pageParams.service_description;
$scope.param = {};
surveilStatus.getService(hostname, serviceDescription).then(function (data) {
$scope.param.service = data[0];
surveilStatus.getServiceMetricNames(hostname, serviceDescription).then(function(metric_names) {
$scope.param.service.iframeUrls = {};
angular.forEach(metric_names, function (metric) {
var metricName = metric.metric_name.substr(7);
$scope.param.service.iframeUrls[metricName] = iframeUrl.getIFrameUrl(metric.metric_name, hostname, serviceDescription);
});
});
});
$scope.components = $scope.options.components;
}]
};
});

View File

@ -1,4 +1,4 @@
<div data-ng-repeat="(metric, iframeUrl) in iframeUrls" class="subcomponent__live subcomponent__small">
<div data-ng-repeat="(metric, iframeUrl) in param.service.iframeUrls" class="subcomponent__live subcomponent__small">
<h2>Graph - {{metric}}</h2>
<iframe src="{{iframeUrl}}" width="450" height="200" frameborder="0"></iframe>
<table class="data-table">

View File

@ -0,0 +1,9 @@
'use strict';
angular.module('bansho.service')
.directive('banshoServiceGraphs', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/service/service_graphs/service_graphs.html'
};
});

View File

@ -1,18 +1,18 @@
<div ng-controller="ServiceInfoCtrl" class="subcomponent__live">
<div class="subcomponent__live">
<h2>Info</h2>
<table class="data-table">
<tbody>
<tr>
<td>Last check</td>
<td>{{service.last_check|timeElapsed}}</td>
<td>{{param.service.service_last_check|timeElapsed}}</td>
</tr>
<tr>
<td>Last state change</td>
<td>{{service.last_state_change|timeElapsed}}</td>
<td>{{param.service.service_last_state_change|timeElapsed}}</td>
</tr>
<tr>
<td>Acknowledged</td>
<td>{{isAcknowledged}}</td>
<td>{{param.service.service_acknowledged ? "Yes" : "No"}}</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,9 @@
'use strict';
angular.module('bansho.service')
.directive('banshoServiceInfo', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/service/service_info/service_info.html'
};
});

View File

@ -0,0 +1,15 @@
<div class="subcomponent__live subcomponent__small">
<h2>Status</h2>
<table class="data-table">
<tbody>
<tr>
<td>State</td>
<td><bansho-service-state-icon state="param.service.service_state"></bansho-service-state-icon> {{param.service.service_state}}</td>
</tr>
<tr>
<td>Output</td>
<td>{{param.service.service_plugin_output}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,9 @@
'use strict';
angular.module('bansho.service')
.directive('banshoServiceLive', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/service/service_live/service_live.html'
};
});

View File

@ -0,0 +1,7 @@
<div class="subcomponent__live subcomponent__title">
<h1>{{param.service.service_service_description}}
<span class="subtitle">
<a class="data-table__data" href="#/view?view=host&host_name={{param.service.service_host_name}}">{{param.service.host_host_name}}</a>
</span>
</h1>
</div>

View File

@ -0,0 +1,12 @@
'use strict';
angular.module('bansho.service')
.directive('banshoServiceMain', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/service/service_main/service_main.html',
link: function (scope) {
scope.param = scope.$parent.param;
}
};
});

View File

@ -0,0 +1,3 @@
<div>
<h2>Metrics</h2>
</div>

View File

@ -1,17 +1,12 @@
'use strict';
angular.module('bansho.service.metrics', [])
.controller('ServiceMetricsCtrl', ['$scope', function ($scope) {
angular.noop();
}])
.directive('banshoServiceMetrics', function () {
return {
restrict: 'E',
scope: {
service: '=service'
},
templateUrl: 'components/service/service_metrics/service_metrics.html'
templateUrl: 'components/service/service_metrics/service_metrics.html',
link: function (scope) {
scope.param = scope.$parent.param;
}
};
});

View File

@ -0,0 +1,3 @@
<td class="data-table__duration">
<time class="data-table__data">{{entry.service_last_state_change | timeElapsed}}</time>
</td>

View File

@ -9,19 +9,19 @@ angular.module('bansho.table.cell_status_event', ['bansho.table'])
};
var shownOutput = {
'attempts': true,
'contact': true,
'notification_method': true,
'notification_type': true,
'state': true,
'state_type': true
'event_attempts': true,
'event_contact': true,
'event_notification_method': true,
'event_notification_type': true,
'event_state': true,
'event_state_type': true
};
$scope.filter = function (entry) {
var result = {};
angular.forEach(entry, function(value, key) {
if (shownOutput[key]) {
result[key] = value;
result[key.substring(6)] = value;
}
});
return result;

View File

@ -0,0 +1,3 @@
<td class="data-table__event_type">
<p class="data-table__data">{{entry.event_event_type}}</p>
</td>

View File

@ -0,0 +1,3 @@
<td class="data-table__event_host_name">
<p class="data-table__data">{{entry.event_host_name}}</p>
</td>

View File

@ -1,3 +1,3 @@
<td class="data-table__event_output" ng-controller="CellStatusEventOutputCtrl">
<p class="data-table__data">{{entry.output}}</p>
<p class="data-table__data">{{entry.event_output}}</p>
</td>

View File

@ -0,0 +1,3 @@
<td class="data-table__event_service_description">
<p class="data-table__data">{{entry.event_service_description}}</p>
</td>

View File

@ -0,0 +1,3 @@
<td class="data-table__time">
<time class="data-table__data">{{entry.event_time}}</time>
</td>

View File

@ -1,3 +1,3 @@
<td class="data-table__host {{entry[cell_name + '_additionnalClass']}} {{state}}" ng-controller="CellStatusHostCtrl">
<a class="data-table__data" href="#/view?view=host&host_name={{entry.host_name}}">{{entry.host_name}}</a>
<a class="data-table__data" href="#/view?view=host&host_name={{entry.host_host_name}}">{{entry.host_host_name}}</a>
</td>

View File

@ -17,6 +17,6 @@ angular.module('bansho.table.cell_status_host', ['bansho.table'])
}])
.run(['tableGlobalConfig', function (tableGlobalConfig) {
tableGlobalConfig.cellToFieldsMap.status_host = ['host_state', 'host_name'];
tableGlobalConfig.cellToFieldsMap.status_host = ['state', 'host_name'];
tableGlobalConfig.cellWrappableField.status_host = 'host_name';
}]);

View File

@ -1,3 +1,3 @@
<td class="data-table__hostaddress" ng-controller="CellStatusHostAddressCtrl">
<span class="data-table__data">{{entry.address}}</span>
<span class="data-table__data">{{entry.host_address}}</span>
</td>

View File

@ -0,0 +1,3 @@
<td class="data-table__lastcheck">
<time class="data-table__data">{{entry.host_last_check * 1000 | date: "medium"}}</time>
</td>

View File

@ -0,0 +1,8 @@
<td class="data-table__service {{state}}" ng-controller="CellStatusServiceCheckCtrl">
<dl class="data-table__data">
<dt class="data-table__service__name">
<a href="#/view?view=service&host_name={{entry.host_host_name}}&description={{entry.service_service_description}}">{{entry.service_service_description}}</a>
</dt>
<dd class="data-table__service__summary">{{entry.service_plugin_output}}</dd>
</dl>
</td>

View File

@ -3,9 +3,9 @@
angular.module('bansho.table.cell_status_service_check', ['bansho.table'])
.controller('CellStatusServiceCheckCtrl', ['$scope', function ($scope) {
if ($scope.entry.state === 'OK') {
if ($scope.entry.service_state === 'OK') {
$scope.state = 'state--ok';
} else if ($scope.entry.state === 'WARNING') {
} else if ($scope.entry.service_state === 'WARNING') {
$scope.state = 'state--warning';
} else {
$scope.state = 'state--error';

View File

@ -0,0 +1,48 @@
'use strict';
angular.module('bansho.table')
.directive('banshoHostStateIcon', function () {
return {
restrict: 'E',
scope: {
state: '='
},
templateUrl: 'components/directive/table/state_icon/state_icon.html',
controller: ['$scope', function ($scope) {
$scope.$watch('state', function (newValue) {
if ($scope.state === 'UP') {
$scope.stateClass = 'state--ok';
} else if ($scope.state === 'WARNING') {
$scope.stateClass = 'state--warning';
} else if ($scope.state === '') {
$scope.stateClass = '';
} else {
$scope.stateClass = 'state--error';
}
});
}]
};
})
.directive('banshoServiceStateIcon', function () {
return {
restrict: 'E',
scope: {
state: '='
},
templateUrl: 'components/directive/table/state_icon/state_icon.html',
controller: ['$scope', function ($scope) {
$scope.$watch('state', function (newValue) {
if ($scope.state === 'OK') {
$scope.stateClass = 'state--ok';
} else if ($scope.state === 'WARNING') {
$scope.state = 'state--warning';
} else if ($scope.state === '') {
$scope.stateClass = '';
} else {
$scope.stateClass = 'state--error';
}
});
}]
};
});

View File

@ -0,0 +1,40 @@
<div>
<header class="main__content__header clearfix">
<h2 data-ng-show="title" class="main__content__title">tets{{title}}</h2>
</header>
<table class="data-table">
<thead class="moving-thead">
<tr>
<th data-ng-show="checkColumn" class="data-table__checkbox">
<md-checkbox aria-label='Check all' ng-model="isCheckAll" ng-change="onCheckChange()"></md-checkbox>
</th>
<th ng-repeat="i in cellIndexes" class="data-table__{{cellsName[i]}}">
{{cellsText[i]}}
<i class="ico-up-dir"></i>
</th>
</tr>
</thead>
<thead class="static-thead">
<tr>
<th data-ng-show="checkColumn" class="data-table__checkbox">
<md-checkbox aria-label='Check all' ng-model="isCheckAll" ng-change="onCheckChange()"></md-checkbox>
</th>
<th ng-repeat="i in cellIndexes" class="data-table__{{cellsName[i]}}">
{{cellsText[i]}}
<i class="ico-up-dir"></i>
</th>
</tr>
</thead>
<tbody class="{{entry.child_class}}"
ng-repeat="(groupByKey, groupByItems) in entries | groupBy:'host_name'">
<tr ng-repeat="entry in groupByItems | noRepeat:this | wrappableStyle:this">
<td data-ng-show="checkColumn">
<md-checkbox aria-label='Check' ng-model="entry.is_checked"></md-checkbox>
</td>
<td bansho-cell cell-name="{{cell}}" ng-repeat="cell in cellsName"></td>
</tr>
</tbody>
</table>
</div>

View File

@ -1,8 +1,8 @@
'use strict';
angular.module('bansho.table', ['bansho.surveil',
'bansho.utils.promiseManager',
'bansho.table.actionbar',
angular.module('bansho.table', ['bansho.utils.promiseManager',
'bansho.datasource',
'bansho.actionbar',
'bansho.filters',
'bansho.table.cell_status_host',
'bansho.table.cell_status_event',
@ -18,92 +18,40 @@ angular.module('bansho.table', ['bansho.surveil',
'ngMaterial'
])
.value('tableGlobalConfig', {'cellToFieldsMap': {}, 'cellWrappableField': {}})
.service('tables', ['$filter', 'surveilStatus', 'tableGlobalConfig',
function ($filter, surveilStatus, tableGlobalConfig) {
var inputSourceServices = {
surveilStatus: surveilStatus
},
config = [],
data = [],
filteredData = [],
listeners = [];
function notifyDataChanged(tableId) {
angular.forEach(listeners[tableId], function (callback) {
callback(filteredData[tableId], config[tableId].isCheckAll);
});
}
function filterData(tableId) {
filteredData[tableId] = $filter('filter')(data[tableId], config[tableId].searchFilter);
notifyDataChanged(tableId);
}
.directive('banshoTable', ['datasource', 'tableGlobalConfig',
function (datasource, tableGlobalConfig) {
return {
refreshTableData: function (tableId) {
var promise = inputSourceServices.surveilStatus.getTableData(
config[tableId].requestFields, config[tableId].inputSource.config);
promise.then(function (newData) {
data[tableId] = newData;
config[tableId].isCheckAll = false;
filterData(tableId);
}, function (error) {
throw new Error('getTableData : Query failed' + error);
});
restrict: 'E',
scope: {
options: '='
},
addTable: function (tableId, conf) {
config[tableId] = conf;
config[tableId].requestFields = [];
angular.forEach(config[tableId].cells.name, function (cell) {
angular.forEach(tableGlobalConfig.cellToFieldsMap[cell], function (_value) {
config[tableId].requestFields.push(_value);
});
});
},
getConfig: function (tableId) {
return config[tableId];
},
forEachCheckedEntry: function (tableId, callbackIsChecked) {
angular.forEach(filteredData[tableId], function (entry) {
if (entry.is_checked) {
callbackIsChecked(entry);
}
});
notifyDataChanged(tableId);
},
registerDataChanged: function (tableId, callback) {
if (!listeners[tableId]) {
listeners[tableId] = [];
}
listeners[tableId].push(callback);
},
setAllCheckTable: function (tableId, isChecked) {
config[tableId].isCheckAll = isChecked;
angular.forEach(filteredData[tableId], function (entry) {
entry.is_checked = isChecked;
});
notifyDataChanged(tableId, isChecked);
},
setSearchFilter: function (tableId, searchFilter) {
config[tableId].searchFilter = searchFilter;
filterData(tableId);
}
};
}])
.controller('TableCtrl', ['$scope', '$interval', 'headerFollow', 'surveilStatus', 'tables', 'tableGlobalConfig', 'promisesManager',
function ($scope, $interval, headerFollow, surveilStatus, tables, tableGlobalConfig,
promisesManager) {
var conf = tables.getConfig($scope.tableId),
globalConfig = tableGlobalConfig,
templateUrl: 'components/directive/table/table.html',
controller: ['$scope', '$interval', 'headerFollow', 'datasource', 'tableGlobalConfig', 'promisesManager', 'pageParams',
function ($scope, $interval, headerFollow, datasource, tableGlobalConfig, promisesManager, pageParams) {
var conf = {},
refreshInterval = pageParams.refreshInterval ? pageParams.refreshInterval : 100000,
i;
if (conf.headerFollow) {
$scope.tableId = $scope.options.attributes.tableId;
// Create table configuration
conf.title = $scope.options.attributes.title;
conf.cells = {'text': [], 'name': []};
conf.cells.text = $scope.options.attributes.cells.text;
conf.cells.name = $scope.options.attributes.cells.name;
conf.inputSource = $scope.options.attributes.inputSource;
conf.isWrappable = $scope.$eval($scope.options.attributes.isWrappable);
conf.noRepeatCell = $scope.options.attributes.noRepeatCell;
datasource.addTable($scope.tableId, conf);
// Handle table layout
$scope.checkColumn = $scope.options.attributes.checkColumn;
if ($scope.options.attributes.headerFollow) {
headerFollow.activate();
} else {
headerFollow.deactivate();
@ -116,68 +64,27 @@ angular.module('bansho.table', ['bansho.surveil',
$scope.cellIndexes.push(i);
}
$scope.onCheckChange = function() {
tables.setAllCheckTable($scope.tableId, $scope.isCheckAll);
$scope.onCheckChange = function () {
datasource.setAllCheckTable($scope.tableId, $scope.isCheckAll);
};
tables.registerDataChanged($scope.tableId, function (data, isCheckAll) {
datasource.registerDataChanged($scope.tableId, function (data, isCheckAll) {
$scope.isCheckAll = isCheckAll;
$scope.entries = data;
});
tables.refreshTableData($scope.tableId);
if (globalConfig.refreshInterval !== 0) {
datasource.refreshTableData($scope.tableId);
if ($scope.options.attributes.refreshInterval && $scope.options.attributes.refreshInterval !== 0) {
promisesManager.addAjaxPromise(
$interval(function () {
tables.refreshTableData($scope.tableId);
}, globalConfig.refreshInterval)
datasource.refreshTableData($scope.tableId);
}, refreshInterval)
);
}
}])
.directive('banshoTable', ['$http', '$compile', 'tables', 'tableGlobalConfig',
function ($http, $compile, tables, tableGlobalConfig) {
return {
restrict: 'E',
scope: {
tableId: '='
},
compile: function () {
return function (scope, element, attrs) {
var template = 'components/table/table.html',
conf = {};
if (!attrs.cellsText || !attrs.cellsName || !attrs.inputSource || !attrs.isWrappable) {
throw new Error('<bansho-table> "cells-text", "cells-name", "inputSource" and "is-wrappable" attributes must be defined');
}
// Create table configuration
conf.cells = { 'text': [], 'name': [] };
conf.cells.text = attrs.cellsText.split(',');
conf.cells.name = attrs.cellsName.split(',');
conf.inputSource = JSON.parse(attrs.inputSource);
conf.isWrappable = JSON.parse(attrs.isWrappable);
conf.noRepeatCell = attrs.noRepeatCell;
conf.headerFollow = scope.$eval(attrs.headerFollow);
tables.addTable(scope.tableId, conf);
scope.checkColumn = scope.$eval(attrs.checkColumn);
if (!!attrs.refreshInterval) {
tableGlobalConfig.refreshInterval = parseInt(attrs.refreshInterval * 1000, 10);
}
$http.get(template, { cache: true })
.success(function (data) {
var elem = $compile(data)(scope);
element.append(elem);
});
}]
};
}
};
}])
])
.directive('banshoCell', ['$http', '$compile', function ($http, $compile) {
return {
@ -188,7 +95,7 @@ angular.module('bansho.table', ['bansho.surveil',
throw new Error('<bansho-cell> "cell-name" attribute must be defined');
}
var template = 'components/table/cell_' + attrs.cellName + '/cell_' + attrs.cellName + '.html';
var template = 'components/directive/table/cell_' + attrs.cellName + '/cell_' + attrs.cellName + '.html';
$http.get(template, { cache: true })
.success(function (data) {
@ -201,33 +108,20 @@ angular.module('bansho.table', ['bansho.surveil',
};
}])
.value('TableConfigObj', function (config) {
this.title = config.title;
this.tableId = config.tableId;
this.CellsText = config.cells.text.join();
this.CellsName = config.cells.name.join();
this.InputSource = config.inputSource;
this.IsWrappable = config.isWrappable;
this.ContainsActionBar = config.containsActionBar;
this.CheckColumn = config.checkColumn;
this.HeaderFollow = config.headerFollow;
this.NoRepeatCell = config.noRepeatCell;
})
.filter('wrappableStyle', ['tables', 'tableGlobalConfig', function (tables, tableGlobalConfig) {
.filter('wrappableStyle', ['datasource', 'tableGlobalConfig', function (datasource, tableGlobalConfig) {
return function (input, scope) {
var last = '',
entry = {},
parent_found = false,
class_name = ['', ''],
i,
fieldToWrap = tableGlobalConfig.cellWrappableField[tables.getConfig(scope.tableId).noRepeatCell];
fieldToWrap = tableGlobalConfig.cellWrappableField[datasource.getConfig(scope.tableId).noRepeatCell];
if (fieldToWrap === undefined) {
return input;
}
if (tables.getConfig(scope.tableId).isWrappable) {
if (datasource.getConfig(scope.tableId).isWrappable) {
class_name = ['state--hasChild', 'state--isChild'];
}
@ -256,12 +150,12 @@ angular.module('bansho.table', ['bansho.surveil',
};
}])
.filter('noRepeat', ['tables', 'tableGlobalConfig', function (tables, tableGlobalConfig) {
.filter('noRepeat', ['datasource', 'tableGlobalConfig', function (datasource, tableGlobalConfig) {
return function (items, scope) {
var newItems = [],
previous,
fieldToCompare = tableGlobalConfig.cellWrappableField[tables.getConfig(scope.tableId).noRepeatCell],
newAttr = tables.getConfig(scope.tableId).noRepeatCell + "_additionnalClass";
fieldToCompare = tableGlobalConfig.cellWrappableField[datasource.getConfig(scope.tableId).noRepeatCell],
newAttr = datasource.getConfig(scope.tableId).noRepeatCell + "_additionnalClass";
angular.forEach(items, function (item) {

View File

@ -0,0 +1,6 @@
<div role="tabpanel" class="tab-pane" data-ng-class="{active: parent.currentPanel === index }"
id="{{options.attributes.panelId}}" data-ng-show="parent.currentPanel === index">
<section class="main__content tabpanel">
<bansho-components components="options.components"></bansho-components>
</section>
</div>

View File

@ -0,0 +1,17 @@
<section class="main__content tabpanel">
<nav>
<ul class="tablist clearfix">
<li role="presentation" class="tablist__item" data-ng-repeat="(index, panel) in navigation"
ng-class="{active: currentPanel === index }">
<a ng-click="setIsShown(index)"
class="tabpanel__tab"
aria-expanded="true"
role="tab"
data-toggle="tab"
data-problems="{{panel.right}}">{{panel.title}}
</a>
</li>
</ul>
</nav>
<bansho-components components="options.components"></bansho-components>
</section>

View File

@ -0,0 +1,50 @@
'use strict';
angular.module('bansho.tabpanel', [])
.directive('banshoTabpanel', ['sharedData', function (sharedData) {
return {
restrict: 'E',
templateUrl: 'components/directive/tabpanel/tabpanel.html',
scope: {
options: '='
},
link: function (scope) {
scope.navigation = scope.options.attributes.navigation;
scope.currentPanel = 0;
scope.setIsShown = function (index) {
scope.currentPanel = index;
};
angular.forEach(scope.options.components, function (panel, index) {
panel.attributes.index = index;
});
angular.forEach(scope.options.attributes.navigation, function (panel, index) {
panel.right = sharedData.getData(panel.provider, 30000, function (data) {
panel.right = data;
});
});
}
};
}])
.directive('banshoPanel', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/tabpanel/panel.html',
scope: {
options: '='
},
link: function (scope) {
if (scope.$parent.$parent.currentPanel !== undefined) {
scope.parent = scope.$parent.$parent;
scope.index = scope.options.attributes.index;
} else {
scope.parent = {};
scope.parent.currentPanel = 0;
scope.index = 0;
}
}
};
});

View File

@ -10,6 +10,6 @@ angular.module('bansho.tactical.current_health', ['bansho.surveil',
.directive('banshoCurrentHealth', function () {
return {
restrict: 'E',
templateUrl: 'components/tactical/current_health/current_health.html'
templateUrl: 'components/directive/tactical/current_health/current_health.html'
};
});

View File

@ -9,6 +9,6 @@ angular.module('bansho.tactical.status_overview', [])
.directive('banshoStatusOverview', function () {
return {
restrict: 'E',
templateUrl: 'components/tactical/status_overview/status_overview.html'
templateUrl: 'components/directive/tactical/status_overview/status_overview.html'
};
});

View File

@ -0,0 +1,19 @@
<header class="main__overview">
<h2 class="main__overview__title">{{title}}</h2>
<div class="panes panes--3" id="tactical">
<div class="panes__container">
<div class="panes__pane" ng-if="statusOverview">
<bansho-status-overview></bansho-status-overview>
</div>
<div class="panes__pane" ng-if="currentHealth">
<bansho-current-health></bansho-current-health>
</div>
<div class="panes__pane" ng-if="topAlertProducers">
<bansho-top-alert-producers></bansho-top-alert-producers>
</div>
</div>
</div>
</header>

View File

@ -0,0 +1,51 @@
'use strict';
angular.module('bansho.tactical', ['bansho.surveil',
'bansho.tactical.status_overview',
'bansho.tactical.current_health',
'bansho.tactical.top_alert_producers'
])
.directive('banshoTactical', function () {
return {
restrict: 'E',
templateUrl: 'components/directive/tactical/tactical.html',
scope: {
options: '='
},
controller: ['$scope', '$interval', 'surveilStatus', 'pageParams', 'sharedData',
function ($scope, $interval, surveilStatus, pageParams, sharedData) {
var refreshInterval = pageParams.refreshInterval ? pageParams.refreshInterval : 100000;
$scope.title = $scope.options.attributes.title;
$scope.statusOverview = $scope.options.attributes.statusOverview;
$scope.currentHealth = $scope.options.attributes.currentHealth;
$scope.topAlertProducers = $scope.options.attributes.topAlertProducers;
$scope.totalHosts = sharedData.getData('nbHosts', refreshInterval, function (data) {
$scope.totalHosts = data;
});
$scope.hostProblems = sharedData.getData('nbHostsOpenProblems', refreshInterval, function (data) {
$scope.hostProblems = data;
$scope.hostsRatio = ($scope.totalHosts - $scope.hostProblems) / $scope.totalHosts * 100;
});
$scope.totalServices = sharedData.getData('nbServices', refreshInterval, function (data) {
$scope.totalServices = data;
});
$scope.serviceProblems = sharedData.getData('nbServicesOpenProblems', refreshInterval, function (data) {
$scope.serviceProblems = data;
$scope.servicesRatio = ($scope.totalServices - $scope.serviceProblems) / $scope.totalServices * 100;
});
// Togglable tabs
// Don't follow hyperlinks
$('a[data-toggle="tab"]').on('click', function (evt) {
evt.preventDefault();
});
}
]
};
});

View File

@ -21,6 +21,6 @@ angular.module('bansho.tactical.top_alert_producers', ['ngRoute' ])
.directive('banshoTopAlertProducers', function () {
return {
restrict: 'E',
templateUrl: 'components/tactical/top_alert_producers/top_alert_producers.html'
templateUrl: 'components/directive/tactical/top_alert_producers/top_alert_producers.html'
};
});

View File

@ -0,0 +1,14 @@
<div class="tab-content">
<header class="main__content__header clearfix">
<h2 class="main__content__title">{{options.attributes.title}}</h2>
<p data-ng-show="isBannerShown" class="main__content__alert state--error">
There
<ng-pluralize count="{{data}}" when="{'0':'is', '1': 'is', 'other': 'are'}">
</ng-pluralize>
are {{data}} {{item}}
<ng-pluralize count="data" when="{'0':'problem', '1': 'problem', 'other': 'problems'}">
</ng-pluralize>
</p>
</header>
</div>

View File

@ -0,0 +1,22 @@
'use strict';
angular.module('bansho.title', [])
.directive('banshoTitle', ['sharedData', function (sharedData) {
return {
restrict: 'E',
templateUrl: 'components/directive/title/title.html',
scope: {
options: '='
},
link: function (scope) {
if (scope.options.attributes.item) {
scope.item = scope.options.attributes.item;
scope.data = sharedData.getData(scope.options.attributes.provider, 30000, function (data) {
scope.data = data;
});
scope.isBannerShown = true;
}
}
};
}]);

View File

@ -1,17 +0,0 @@
<article ng-controller="HostCtrl">
<section class="main__content tabpanel" ng-if="data.live && data.config">
<bansho-host-main></bansho-host-main>
<bansho-host-live></bansho-host-live>
<bansho-host-load></bansho-host-load>
<bansho-host-cpu></bansho-host-cpu>
<bansho-host-info></bansho-host-info>
<bansho-host-services-list></bansho-host-services-list>
</section>
</article>

View File

@ -1,68 +0,0 @@
'use strict';
angular.module('bansho.host', ['bansho.surveil',
'bansho.host.main',
'bansho.host.live',
'bansho.host.load',
'bansho.host.cpu',
'bansho.host.info',
'bansho.host.services_list'])
.value('hostConfig', {})
.controller('HostCtrl', ['$scope', 'hostConfig', 'surveilStatus', function ($scope, hostConfig, surveilStatus) {
var objectType = 'host',
objectIdentifier = {};
objectIdentifier.host_name = hostConfig.hostName;
surveilStatus.getHost(objectType, objectIdentifier).then(function (data) {
$scope.host = data;
$scope.data = data;
surveilStatus.getServicesByHost($scope.hostName).success(function (data) {
var i,
service;
$scope.host.services = data;
for (i = 0; i < $scope.host.services.length;) {
service = $scope.host.services[i];
if (service.service_description === "cpu") {
$scope.host.cpuService = service;
$scope.host.services.splice(i, 1);
} else if (service.service_description === "load") {
$scope.host.loadService = service;
$scope.host.services.splice(i, 1);
} else {
++i;
}
}
});
});
}])
.directive('banshoHost', ['$http', '$compile', 'surveilStatus', 'hostConfig',
function ($http, $compile, surveilStatus, hostConfig) {
return {
restrict: 'E',
compile: function () {
return function (scope, element, attrs) {
var template = 'components/host/host.html';
if (!attrs.hostName) {
throw new Error('<bansho-host> "host-name" attribute must be defined');
}
hostConfig.hostName = {};
hostConfig.hostName = attrs.hostName;
$http.get(template, { cache: true })
.success(function (data) {
var elem = $compile(data)(scope);
element.append(elem);
});
};
}
};
}]);

View File

@ -1,15 +0,0 @@
<div data-ng-show="host.cpuService" class="subcomponent__live subcomponent__small">
<h2>Cpu</h2>
<table class="data-table">
<tbody>
<tr>
<td>State</td>
<td><bansho-service-state-icon state="host.cpuService.state"></bansho-service-state-icon> {{host.cpuService.state}}</td>
</tr>
<tr>
<td>Output</td>
<td>{{host.cpuService.plugin_output}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -1,12 +0,0 @@
'use strict';
angular.module('bansho.host.cpu', ['bansho.surveil'])
.directive('banshoHostCpu', function () {
return {
restrict: 'E',
compile: function (scope, element, attrs) {
scope.host = attrs.host;
},
templateUrl: 'components/host/host_cpu/host_cpu.html'
};
});

Some files were not shown because too many files have changed in this diff Show More