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':
+ '' +
+ ' {{ label }}' +
+ ''
+ };
+});
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);
}
};
});