'use strict'; angular.module('ffffngAdmin').config(function(NgAdminConfigurationProvider, RestangularProvider, Constraints, config) { RestangularProvider.addFullRequestInterceptor(function(element, operation, what, url, headers, params) { if (operation === 'getList') { if (params._filters) { // flatten filter query params for (var filter in params._filters) { params[filter] = params._filters[filter]; } delete params._filters; } } return { params: params }; }); function nullable(value) { return value ? value : 'N/A'; } function formatMoment(unix) { return unix ? moment.unix(unix).fromNow() : 'N/A'; } function formatDuration(duration) { return typeof duration === 'number' ? moment.duration(duration).humanize() : 'N/A'; } function nodeConstraint(field) { var constraint = Constraints.node[field]; var result = { required: !constraint.optional }; if (constraint.type === 'string') { result.pattern = constraint.regex; } return result; } var nga = NgAdminConfigurationProvider; var title = 'Knotenverwaltung - ' + config.community.name + ' - Admin-Panel'; var admin = nga.application(title); document.title = title; var pathPrefix = config.rootPath === '/' ? '' : config.rootPath; admin .header( '' + '' + '' + '' ) .baseApiUrl(pathPrefix + '/internal/api/') .debug(true); function nodeClasses(node) { if (!node) { return; } switch (node.values.onlineState) { case 'ONLINE': return 'node-online'; case 'OFFLINE': return 'node-offline'; default: return; } } var nodes = nga.entity('nodes').label('Nodes').identifier(nga.field('token')); nodes .listView() .title('Nodes') .perPage(30) .sortDir('ASC') .sortField('hostname') .actions([]) .batchActions([]) .exportFields([]) .fields([ nga.field('hostname').cssClasses(nodeClasses), nga.field('nickname').cssClasses(nodeClasses), nga.field('email').cssClasses(nodeClasses), nga.field('token').cssClasses(nodeClasses), nga.field('mac').cssClasses(nodeClasses), nga.field('key').label('VPN').cssClasses(nodeClasses).template(function (node) { return node.values.key ? '' : ''; }), nga.field('coords').label('GPS').cssClasses(nodeClasses).template(function (node) { return node.values.coords ? '' : ''; }), nga.field('onlineState').map(nullable).cssClasses(nodeClasses), nga.field('monitoringState').cssClasses(nodeClasses).template(function (node) { switch (node.values.monitoringState) { case 'active': return ''; case 'pending': return ''; default: return ''; } }) ]) .filters([ nga.field('q', 'template') .label('') .pinned(true) .template( '
' + '' + '
'), nga.field('hasKey', 'choice') .label('VPN key') .pinned(false) .choices([ { label: 'VPN key set', value: true }, { label: 'no VPN key', value: false } ]), nga.field('hasCoords', 'choice') .label('GPS coordinates') .pinned(false) .choices([ { label: 'coordinates set', value: true }, { label: 'no coordinates', value: false } ]), nga.field('onlineState', 'choice') .label('Online state') .pinned(false) .choices([ { label: 'online', value: 'ONLINE' }, { label: 'offline', value: 'OFFLINE' } ]), nga.field('monitoringState', 'choice') .label('Monitoring') .pinned(false) .choices([ { label: 'pending', value: 'pending' }, { label: 'active', value: 'active' }, { label: 'disabled', value: 'disabled' } ]) ]) .actions(['']) .listActions( ' ' + ' ' + '
' + '' + '' + '
' + ' Map' ) ; nodes .editionView() .title('Edit node') .actions(['list', 'delete']) .addField(nga.field('token').editable(false)) .addField(nga.field('hostname').label('Name').validation(nodeConstraint('hostname'))) .addField(nga.field('key').label('Key').validation(nodeConstraint('key'))) .addField(nga.field('mac').label('MAC').validation(nodeConstraint('mac'))) .addField(nga.field('coords').label('GPS').validation(nodeConstraint('coords'))) .addField(nga.field('nickname').validation(nodeConstraint('nickname'))) .addField(nga.field('email').validation(nodeConstraint('email'))) .addField(nga.field('monitoring', 'boolean').validation(nodeConstraint('monitoring'))) .addField(nga.field('monitoringConfirmed').label('Monitoring confirmation').editable(false).map( function (monitoringConfirmed, node) { if (!node.monitoring) { return 'N/A'; } return monitoringConfirmed ? 'confirmed' : 'pending'; } )) ; admin.addEntity(nodes); function monitoringStateClasses(monitoringState) { if (!monitoringState) { return; } switch (monitoringState.values.state) { case 'ONLINE': return 'monitoring-state-online'; case 'OFFLINE': return 'monitoring-state-offline'; default: return; } } var monitoringStates = nga.entity('monitoring').label('Monitoring'); monitoringStates .listView() .title('Monitoring') .perPage(30) .sortDir('ASC') .sortField('id') .actions([]) .batchActions([]) .exportFields([]) .fields([ nga.field('id').cssClasses(monitoringStateClasses), nga.field('hostname').cssClasses(monitoringStateClasses), nga.field('mac').cssClasses(monitoringStateClasses), nga.field('monitoring_state').cssClasses(monitoringStateClasses).template(function (monitoringState) { switch (monitoringState.values.monitoring_state) { case 'active': return ''; case 'pending': return ''; default: return ''; } }), nga.field('state').cssClasses(monitoringStateClasses), nga.field('last_seen').map(formatMoment).cssClasses(monitoringStateClasses), nga.field('import_timestamp').label('Imported').map(formatMoment).cssClasses(monitoringStateClasses), nga.field('last_status_mail_type').map(nullable).cssClasses(monitoringStateClasses), nga.field('last_status_mail_sent').map(formatMoment).cssClasses(monitoringStateClasses), nga.field('created_at').map(formatMoment).cssClasses(monitoringStateClasses), nga.field('modified_at').map(formatMoment).cssClasses(monitoringStateClasses) ]) .filters([ nga.field('q') .label('') .pinned(true) .template( '
' + '' + '
'), ]) .listActions( ' Map' ) ; admin.addEntity(monitoringStates); function mailClasses(mail) { if (!mail) { return; } var failures = mail.values.failures; if (failures === 0) { return 'mails-pending'; } if (failures >= 5) { return 'mails-failed-max'; } return 'mails-failed'; } var mails = nga.entity('mails').label('Mail-Queue'); mails .listView() .title('Mail-Queue') .perPage(30) .sortDir('ASC') .sortField('id') .actions([]) .batchActions([]) .exportFields([]) .fields([ nga.field('id').cssClasses(mailClasses), nga.field('failures').cssClasses(mailClasses), nga.field('sender').cssClasses(mailClasses), nga.field('recipient').cssClasses(mailClasses), nga.field('email').cssClasses(mailClasses), nga.field('created_at').map(formatMoment).cssClasses(mailClasses), nga.field('modified_at').map(formatMoment).cssClasses(mailClasses) ]) .filters([ nga.field('q') .label('') .pinned(true) .template( '
' + '' + '
'), ]) .listActions( ' ' + '' ) ; admin.addEntity(mails); function taskClasses(field) { return function(task) { if (!task) { return; } return 'task-' + field + ' ' + (task.values.enabled ? 'task-enabled' : 'task-disabled'); }; } var tasks = nga.entity('tasks').label('Background-Jobs'); tasks .listView() .title('Background-Jobs') .perPage(30) .sortDir('ASC') .sortField('id') .actions([]) .batchActions([]) .exportFields([]) .fields([ nga.field('id').cssClasses(taskClasses('id')), nga.field('name').cssClasses(taskClasses('name')), nga.field('description').cssClasses(taskClasses('description')), nga.field('schedule').cssClasses(taskClasses('schedule')), nga.field('state').cssClasses(taskClasses('state')), nga.field('runningSince').map(formatMoment).cssClasses(taskClasses('runningSince')), nga.field('lastRunStarted').map(formatMoment).cssClasses(taskClasses('lastRunStarted')), nga.field('lastRunDuration').map(formatDuration).cssClasses(taskClasses('lastRunDuration')) ]) .filters([ nga.field('q') .label('') .pinned(true) .template( '
' + '' + '
'), ]) .listActions( ' ' + ' ' + '' ) ; admin.addEntity(tasks); admin.menu( nga.menu() .addChild(nga .menu() .template( '' + ' Dashboard / Statistics' + '' ) ) .addChild(nga .menu(nodes) .icon('') ) .addChild(nga .menu(monitoringStates) .icon('') ) .addChild(nga .menu(mails) .icon('') ) .addChild(nga .menu(tasks) .icon('') ) .addChild(nga .menu() .template( '' + ' Logs' + '' ) ) ); admin.dashboard(nga.dashboard() .template( '
' + '' + '
' + '
' + '
' + '' + '
' + '
' + '
' ) ); nga.configure(admin); });