Sorting of tasks and nodes in admin panel.
This commit is contained in:
parent
ce2359a094
commit
954b7a3920
|
@ -35,6 +35,8 @@ angular.module('ffffngAdmin').config(function(NgAdminConfigurationProvider, Cons
|
||||||
.listView()
|
.listView()
|
||||||
.title('Nodes')
|
.title('Nodes')
|
||||||
.perPage(30)
|
.perPage(30)
|
||||||
|
.sortDir('ASC')
|
||||||
|
.sortField('hostname')
|
||||||
.actions([])
|
.actions([])
|
||||||
.batchActions([])
|
.batchActions([])
|
||||||
.exportFields([])
|
.exportFields([])
|
||||||
|
@ -52,13 +54,17 @@ angular.module('ffffngAdmin').config(function(NgAdminConfigurationProvider, Cons
|
||||||
? '<i class="fa fa-map-marker coords-set" aria-hidden="true" title="coordinates set"></i>'
|
? '<i class="fa fa-map-marker coords-set" aria-hidden="true" title="coordinates set"></i>'
|
||||||
: '<i class="fa fa-times coords-unset" aria-hidden="true" title="no coordinates"></i>';
|
: '<i class="fa fa-times coords-unset" aria-hidden="true" title="no coordinates"></i>';
|
||||||
}),
|
}),
|
||||||
nga.field('monitoring').cssClasses(nodeClasses).template(function (node) {
|
nga.field('monitoringState').cssClasses(nodeClasses).template(function (node) {
|
||||||
if (!node.values.monitoring) {
|
switch (node.values.monitoringState) {
|
||||||
|
case 'active':
|
||||||
|
return '<i class="fa fa-check monitoring-active" title="active"></i>';
|
||||||
|
|
||||||
|
case 'pending':
|
||||||
|
return '<i class="fa fa-envelope monitoring-confirmation-pending" title="confirmation pending"></i>';
|
||||||
|
|
||||||
|
default:
|
||||||
return '<i class="fa fa-times monitoring-disabled" title="disabled"></i>';
|
return '<i class="fa fa-times monitoring-disabled" title="disabled"></i>';
|
||||||
}
|
}
|
||||||
return node.values.monitoringConfirmed
|
|
||||||
? '<i class="fa fa-check monitoring-active" title="active"></i>'
|
|
||||||
: '<i class="fa fa-envelope monitoring-confirmation-pending" title="confirmation pending"></i>';
|
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
.listActions([
|
.listActions([
|
||||||
|
@ -104,6 +110,8 @@ angular.module('ffffngAdmin').config(function(NgAdminConfigurationProvider, Cons
|
||||||
.listView()
|
.listView()
|
||||||
.title('Background-Jobs')
|
.title('Background-Jobs')
|
||||||
.perPage(30)
|
.perPage(30)
|
||||||
|
.sortDir('ASC')
|
||||||
|
.sortField('id')
|
||||||
.actions([])
|
.actions([])
|
||||||
.batchActions([])
|
.batchActions([])
|
||||||
.exportFields([])
|
.exportFields([])
|
||||||
|
|
|
@ -100,15 +100,22 @@ angular.module('ffffng').factory('NodeResource', function (
|
||||||
return Resources.error(res, err);
|
return Resources.error(res, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Sort + Filter
|
// TODO: Filter
|
||||||
|
|
||||||
return NodeService.getAllNodes(restParams._page, restParams._perPage, function (err, nodes, total) {
|
return NodeService.getAllNodes(function (err, nodes, total) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return Resources.error(res, err);
|
return Resources.error(res, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sortedNodes = Resources.sort(
|
||||||
|
nodes,
|
||||||
|
['token', 'mac', 'hostname', 'key', 'coords', 'monitoringState'],
|
||||||
|
restParams
|
||||||
|
);
|
||||||
|
var pageNodes = Resources.getPageEntities(sortedNodes, restParams);
|
||||||
|
|
||||||
res.set('X-Total-Count', total);
|
res.set('X-Total-Count', total);
|
||||||
return Resources.success(res, nodes);
|
return Resources.success(res, pageNodes);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,15 +79,14 @@ angular.module('ffffng').factory('TaskResource', function (
|
||||||
return Resources.error(res, err);
|
return Resources.error(res, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Sort
|
var tasks = Resources.sort(
|
||||||
|
_.values(Scheduler.getTasks()),
|
||||||
var tasks = _.values(Scheduler.getTasks());
|
['id', 'name', 'schedule', 'state', 'runningSince', 'lastRunStarted'],
|
||||||
|
restParams
|
||||||
|
);
|
||||||
var total = tasks.length;
|
var total = tasks.length;
|
||||||
|
|
||||||
var page = restParams._page;
|
var pageTasks = Resources.getPageEntities(tasks, restParams);
|
||||||
var perPage = restParams._perPage;
|
|
||||||
|
|
||||||
var pageTasks = tasks.slice((page - 1) * perPage, page * perPage);
|
|
||||||
|
|
||||||
res.set('X-Total-Count', total);
|
res.set('X-Total-Count', total);
|
||||||
return Resources.success(res, _.map(pageTasks, toExternalTask));
|
return Resources.success(res, _.map(pageTasks, toExternalTask));
|
||||||
|
|
|
@ -217,6 +217,7 @@ angular.module('ffffng')
|
||||||
var pending = value === 'pending';
|
var pending = value === 'pending';
|
||||||
node.monitoring = active || pending;
|
node.monitoring = active || pending;
|
||||||
node.monitoringConfirmed = active;
|
node.monitoringConfirmed = active;
|
||||||
|
node.monitoringState = active ? 'active' : (pending ? 'pending' : '');
|
||||||
} else if (key === 'monitoringToken') {
|
} else if (key === 'monitoringToken') {
|
||||||
nodeSecrets.monitoringToken = value;
|
nodeSecrets.monitoringToken = value;
|
||||||
} else {
|
} else {
|
||||||
|
@ -369,13 +370,12 @@ angular.module('ffffng')
|
||||||
deleteNodeFile(token, callback);
|
deleteNodeFile(token, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
getAllNodes: function (page, perPage, callback) {
|
getAllNodes: function (callback) {
|
||||||
var files = _.sortBy(findNodeFiles({}));
|
var files = findNodeFiles({});
|
||||||
var total = files.length;
|
var total = files.length;
|
||||||
var pageFiles = files.slice((page - 1) * perPage, page * perPage);
|
|
||||||
|
|
||||||
async.mapLimit(
|
async.mapLimit(
|
||||||
pageFiles,
|
files,
|
||||||
MAX_PARALLEL_NODES_PARSING,
|
MAX_PARALLEL_NODES_PARSING,
|
||||||
parseNodeFile,
|
parseNodeFile,
|
||||||
function (err, nodes) {
|
function (err, nodes) {
|
||||||
|
|
|
@ -36,6 +36,24 @@ angular.module('ffffng').factory('Resources', function (_, Constraints, Validato
|
||||||
callback(null, restParams);
|
callback(null, restParams);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
sort: function (entities, allowedSortFields, restParams) {
|
||||||
|
var sortField = _.indexOf(allowedSortFields, restParams._sortField) >= 0 ? restParams._sortField : undefined;
|
||||||
|
if (!sortField) {
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sorted = _.sortBy(entities, [sortField]);
|
||||||
|
|
||||||
|
return restParams._sortDir === 'ASC' ? sorted : _.reverse(sorted);
|
||||||
|
},
|
||||||
|
|
||||||
|
getPageEntities: function (entities, restParams) {
|
||||||
|
var page = restParams._page;
|
||||||
|
var perPage = restParams._perPage;
|
||||||
|
|
||||||
|
return entities.slice((page - 1) * perPage, page * perPage);
|
||||||
|
},
|
||||||
|
|
||||||
success: function (res, data) {
|
success: function (res, data) {
|
||||||
respond(res, 200, data);
|
respond(res, 200, data);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ffffng').factory('Validator', function (_, Strings, Logger) {
|
angular.module('ffffng').factory('Validator', function (_, Strings, Logger) {
|
||||||
|
// TODO: sanitize input for further processing as specified by constraints (correct types, trimming, etc.)
|
||||||
|
|
||||||
function isValidBoolean(value) {
|
function isValidBoolean(value) {
|
||||||
return _.isBoolean(value);
|
return _.isBoolean(value) || value === 'true' || value === 'false';
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidNumber(constraint, value) {
|
function isValidNumber(constraint, value) {
|
||||||
|
@ -29,6 +31,14 @@ angular.module('ffffng').factory('Validator', function (_, Strings, Logger) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isValidEnum(constraint, value) {
|
||||||
|
if (!_.isString(value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.indexOf(constraint.allowed, value) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
function isValidString(constraint, value) {
|
function isValidString(constraint, value) {
|
||||||
if (!_.isString(value)) {
|
if (!_.isString(value)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -50,6 +60,9 @@ angular.module('ffffng').factory('Validator', function (_, Strings, Logger) {
|
||||||
case 'number':
|
case 'number':
|
||||||
return isValidNumber(constraint, value);
|
return isValidNumber(constraint, value);
|
||||||
|
|
||||||
|
case 'enum':
|
||||||
|
return isValidEnum(constraint, value);
|
||||||
|
|
||||||
case 'string':
|
case 'string':
|
||||||
return isValidString(constraint, value);
|
return isValidString(constraint, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,17 @@ angular.module('ffffng').constant('Constraints', {
|
||||||
max: 50,
|
max: 50,
|
||||||
optional: true,
|
optional: true,
|
||||||
default: 20
|
default: 20
|
||||||
|
},
|
||||||
|
_sortDir: {
|
||||||
|
type: 'enum',
|
||||||
|
allowed: ['ASC', 'DESC'],
|
||||||
|
optional: true,
|
||||||
|
default: 'ASC'
|
||||||
|
},
|
||||||
|
_sortField: {
|
||||||
|
type: 'string',
|
||||||
|
regex: /^[a-zA-Z0-9_]{1,32}$/,
|
||||||
|
optional: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue