Added Statistics

See: https://github.com/freifunkhamburg/ffffng/issues/24
This commit is contained in:
baldo 2016-07-19 13:24:43 +02:00
parent 2d5db51d24
commit 3c80be4d00
8 changed files with 203 additions and 0 deletions

View file

@ -75,6 +75,7 @@
<script src="js/validation/constraints.js"></script>
<script src="js/views/version.js"></script>
<script src="js/views/dashboardStats.js"></script>
<script src="js/views/mailActionButton.js"></script>
<script src="js/views/taskActionButton.js"></script>

View file

@ -337,6 +337,14 @@ angular.module('ffffngAdmin').config(function(NgAdminConfigurationProvider, Rest
admin.menu(
nga.menu()
.addChild(nga
.menu()
.template(
'<a href="/internal/admin">' +
'<span class="fa fa-dashboard"></span> Dashboard / Statistics' +
'</a>'
)
)
.addChild(nga
.menu(nodes)
.icon('<i class="fa fa-dot-circle-o"></i>')
@ -363,5 +371,20 @@ angular.module('ffffngAdmin').config(function(NgAdminConfigurationProvider, Rest
)
);
admin.dashboard(nga.dashboard()
.template(
'<div class="row dashboard-starter"></div>' +
'<fa-dashboard-stats></fa-dashboard-stats>' +
'<div class="row dashboard-content">' +
'<div class="col-lg-6">' +
'<div class="panel panel-default" ng-repeat="collection in dashboardController.collections | orderElement" ng-if="$even">' +
'<ma-dashboard-panel collection="collection" entries="dashboardController.entries[collection.name()]"></ma-dashboard-panel>' +
'</div>' +
'</div>' +
'</div>'
)
);
nga.configure(admin);
});

View file

@ -0,0 +1,22 @@
'use strict';
angular.module('ffffngAdmin')
.directive('faDashboardStats', function ($http, $state, notification) {
var link = function (scope) {
scope.stats = {};
$http.get('/internal/api/statistics')
.then(function (result) { scope.stats = result.data; })
.catch(function (e) {
notification.log('Error: ' + e.data, { addnCls: 'humane-flatty-error' });
console.error(e);
});
};
return {
'link': link,
'restrict': 'E',
'scope': {},
'templateUrl': 'views/dashboardStats.html'
};
});

View file

@ -0,0 +1,88 @@
<div class="page-header">
<h1>Dashboard / Statistics</h1>
</div>
<h2><a ui-sref="list({entity:'nodes'})">Nodes</a></h2>
<div class="row">
<div class="col-lg-3">
<div class="panel panel-primary">
<div class="panel-heading">
<div class="row">
<div class="col-xs-3">
<i class="fa fa-circle-o fa-5x"></i>
</div>
<div class="col-xs-9 text-right">
<div class="huge">{{ stats.nodes.registered }}</div>
<div>Total Registered</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="panel panel-yellow">
<div class="panel-heading">
<div class="row">
<div class="col-xs-3">
<i class="fa fa-lock fa-5x"></i>
</div>
<div class="col-xs-9 text-right">
<div class="huge">{{ stats.nodes.withVPN }}</div>
<div>With VPN-Key</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="panel panel-green">
<div class="panel-heading">
<div class="row">
<div class="col-xs-3">
<i class="fa fa-map-marker fa-5x"></i>
</div>
<div class="col-xs-9 text-right">
<div class="huge">{{ stats.nodes.withCoords }}</div>
<div>With Coordinates</div>
</div>
</div>
</div>
</div>
</div>
</div>
<h2><a ui-sref="list({entity:'monitoring'})">Monitoring</a></h2>
<div class="row">
<div class="col-lg-3">
<div class="panel panel-green">
<div class="panel-heading">
<div class="row">
<div class="col-xs-3">
<i class="fa fa-heartbeat fa-5x"></i>
</div>
<div class="col-xs-9 text-right">
<div class="huge">{{ stats.nodes.monitoring.active }}</div>
<div>Active</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="panel panel-red">
<div class="panel-heading">
<div class="row">
<div class="col-xs-3">
<i class="fa fa-envelope fa-5x"></i>
</div>
<div class="col-xs-9 text-right">
<div class="huge">{{ stats.nodes.monitoring.pending }}</div>
<div>Pending</div>
</div>
</div>
</div>
</div>
</div>
</div>

View file

@ -29,6 +29,7 @@ require('./utils/strings');
require('./utils/urlBuilder');
require('./resources/versionResource');
require('./resources/statisticsResource');
require('./resources/frontendResource');
require('./resources/taskResource');
require('./resources/mailResource');

View file

@ -0,0 +1,26 @@
'use strict';
angular.module('ffffng').factory('StatisticsResource', function (
Logger,
NodeService,
Resources,
ErrorTypes
) {
return {
get: function (req, res) {
NodeService.getNodeStatistics(function (err, nodeStatistics) {
if (err) {
Logger.tag('statistics').error('Error getting statistics:', err);
return Resources.error(res, {data: 'Internal error.', type: ErrorTypes.internalError});
}
return Resources.success(
res,
{
nodes: nodeStatistics
}
);
});
}
};
});

View file

@ -3,6 +3,7 @@
angular.module('ffffng').factory('Router', function (
app,
VersionResource,
StatisticsResource,
FrontendResource,
NodeResource,
MonitoringResource,
@ -23,6 +24,8 @@ angular.module('ffffng').factory('Router', function (
app.put('/api/monitoring/confirm/:token', MonitoringResource.confirm);
app.put('/api/monitoring/disable/:token', MonitoringResource.disable);
app.get('/internal/api/statistics', StatisticsResource.get);
app.get('/internal/api/tasks', TaskResource.getAll);
app.put('/internal/api/tasks/run/:id', TaskResource.run);
app.put('/internal/api/tasks/enable/:id', TaskResource.enable);

View file

@ -490,6 +490,45 @@ angular.module('ffffng')
callback
);
});
},
getNodeStatistics: function (callback) {
this.getAllNodes(function (err, nodes) {
if (err) {
return callback(err);
}
var nodeStatistics = {
registered: _.size(nodes),
withVPN: 0,
withCoords: 0,
monitoring: {
active: 0,
pending: 0
}
};
_.each(nodes, function (node) {
if (node.key) {
nodeStatistics.withVPN += 1;
}
if (node.coords) {
nodeStatistics.withCoords += 1;
}
switch (node.monitoringState) {
case 'active':
nodeStatistics.monitoring.active += 1;
break;
case 'pending':
nodeStatistics.monitoring.pending += 1;
break;
}
});
callback(null, nodeStatistics);
})
}
};
});