diff --git a/Gruntfile.js b/Gruntfile.js index 3704daa..74f5747 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -371,6 +371,12 @@ module.exports = function (grunt) { cwd: 'bin', dest: '<%= yeoman.dist %>/bin', src: ['*'] + }, + { + expand: true, + cwd: 'admin', + dest: '<%= yeoman.dist %>/admin', + src: ['{,**}/*.*'] } ] }, diff --git a/admin/css/ng-admin.min.css b/admin/css/ng-admin.min.css new file mode 120000 index 0000000..48418bc --- /dev/null +++ b/admin/css/ng-admin.min.css @@ -0,0 +1 @@ +../../node_modules/ng-admin/build/ng-admin.min.css \ No newline at end of file diff --git a/admin/css/ng-admin.min.css.map b/admin/css/ng-admin.min.css.map new file mode 120000 index 0000000..901d1f7 --- /dev/null +++ b/admin/css/ng-admin.min.css.map @@ -0,0 +1 @@ +../../node_modules/ng-admin/build/ng-admin.min.css.map \ No newline at end of file diff --git a/admin/index.html b/admin/index.html new file mode 100644 index 0000000..c562c22 --- /dev/null +++ b/admin/index.html @@ -0,0 +1,15 @@ + + + + Knotenverwaltung - Admin-Panel + + + +
+ + + + + + + diff --git a/admin/js/config.js b/admin/js/config.js new file mode 100644 index 0000000..91ad6c0 --- /dev/null +++ b/admin/js/config.js @@ -0,0 +1,55 @@ +'use strict'; + +var myApp = angular.module('ffffngAdmin', ['ng-admin']); + +myApp.config(['NgAdminConfigurationProvider', function(NgAdminConfigurationProvider) { + function formatMoment(unix) { + return unix ? moment.unix(unix).fromNow() : 'N/A'; + } + + var nga = NgAdminConfigurationProvider; + var admin = nga.application('Knotenverwaltung - Admin-Panel'); + + admin + .baseApiUrl('/internal/api/') + .debug(true); + + var tasks = nga.entity('tasks').label('Background-Jobs'); + tasks + .listView() + .title('Background-Jobs') + .actions([]) + .batchActions([]) + .exportFields([]) + .fields([ + nga.field('id'), + nga.field('name'), + nga.field('schedule'), + nga.field('runningSince').map(formatMoment), + nga.field('lastRunStarted').map(formatMoment) + ]) + .listActions( + '' + ) + ; + + admin.addEntity(tasks); + + admin.menu( + nga.menu() + .addChild(nga + .menu(tasks) + .icon('') + ) + .addChild(nga + .menu() + .template( + '' + + ' Logs' + + '' + ) + ) + ); + + nga.configure(admin); +}]); diff --git a/admin/js/moment-with-locales.min.js b/admin/js/moment-with-locales.min.js new file mode 120000 index 0000000..11ef1e0 --- /dev/null +++ b/admin/js/moment-with-locales.min.js @@ -0,0 +1 @@ +../../node_modules/moment/min/moment-with-locales.min.js \ No newline at end of file diff --git a/admin/js/ng-admin.min.js b/admin/js/ng-admin.min.js new file mode 120000 index 0000000..bd8e0fd --- /dev/null +++ b/admin/js/ng-admin.min.js @@ -0,0 +1 @@ +../../node_modules/ng-admin/build/ng-admin.min.js \ No newline at end of file diff --git a/admin/js/ng-admin.min.js.map b/admin/js/ng-admin.min.js.map new file mode 120000 index 0000000..45fd08a --- /dev/null +++ b/admin/js/ng-admin.min.js.map @@ -0,0 +1 @@ +../../node_modules/ng-admin/build/ng-admin.min.js.map \ No newline at end of file diff --git a/admin/js/taskActionButton.js b/admin/js/taskActionButton.js new file mode 100644 index 0000000..4e1582a --- /dev/null +++ b/admin/js/taskActionButton.js @@ -0,0 +1,39 @@ +'use strict'; + +angular.module('ffffngAdmin') +.directive('faTaskActionButton', function (Restangular, $state, notification) { + var link = function (scope) { + scope.label = scope.label || 'ACTION'; + scope.icon = scope.icon || 'play'; + + scope.perform = function () { + var task = scope.task(); + + Restangular + .one('/internal/api/tasks/' + scope.action, task.values.id).put() + .then(function () { $state.reload() }) + .then(function () { notification.log('Done', { addnCls: 'humane-flatty-success' }); }) + .catch(function (e) { + notification.log('Error: ' + e.data, { addnCls: 'humane-flatty-error' }); + console.error(e) + }); + }; + }; + + return { + 'link': link, + 'restrict': 'E', + 'scope': { + 'action': '@', + 'icon': '@', + 'task': '&', + 'size': '@', + 'label': '@' + }, + + 'template': + '' + + ' ' + + '' + }; +}); diff --git a/package.json b/package.json index 05d01d4..a67efae 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "load-grunt-tasks": "~3.5.0", "lodash": "~4.12.0", "moment": "~2.13.0", + "ng-admin": "~0.9.1", "ng-di": "~0.2.1", "node-cron": "~1.1.1", "nodemailer": "~2.4.1", diff --git a/server/app.js b/server/app.js index 953c0e9..10dbbc2 100644 --- a/server/app.js +++ b/server/app.js @@ -25,6 +25,7 @@ angular.module('ffffng').factory('app', function (fs, config, _) { app.use(bodyParser.json()); + var adminDir = __dirname + '/../admin'; var clientDir = __dirname + '/../client'; var templateDir = __dirname + '/templates'; @@ -54,6 +55,7 @@ angular.module('ffffng').factory('app', function (fs, config, _) { return next(); }); + app.use('/internal/admin', express.static(adminDir + '/')); app.use('/', express.static(clientDir + '/')); return app; diff --git a/server/resources/taskResource.js b/server/resources/taskResource.js index d6e6e7b..305121d 100644 --- a/server/resources/taskResource.js +++ b/server/resources/taskResource.js @@ -11,8 +11,9 @@ angular.module('ffffng').factory('TaskResource', function ( ) { var isValidId = Validator.forConstraint(Constraints.id); - function toExternalTask(task) { + function toExternalTask(task, id) { return { + id: id, name: task.name, schedule: task.schedule, runningSince: task.runningSince && task.runningSince.unix(), @@ -23,7 +24,7 @@ angular.module('ffffng').factory('TaskResource', function ( return { getAll: function (req, res) { var tasks = Scheduler.getTasks(); - return Resources.success(res, _.mapValues(tasks, toExternalTask)); + return Resources.success(res, _.map(tasks, toExternalTask)); }, run: function (req, res) { @@ -46,7 +47,7 @@ angular.module('ffffng').factory('TaskResource', function ( task.run(); - return Resources.success(res, toExternalTask(task)); + return Resources.success(res, toExternalTask(task, id)); } }; }); diff --git a/server/router.js b/server/router.js index afed5a8..5bb4bbf 100644 --- a/server/router.js +++ b/server/router.js @@ -16,8 +16,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/task/all', TaskResource.getAll); - app.put('/internal/api/task/run/:id', TaskResource.run); + app.get('/internal/api/tasks', TaskResource.getAll); + app.put('/internal/api/tasks/run/:id', TaskResource.run); } }; });