Initial commit.
This commit is contained in:
commit
0335f5aa93
1168 changed files with 261999 additions and 0 deletions
47
app/scripts/app.js
Normal file
47
app/scripts/app.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng', [
|
||||
'ngSanitize',
|
||||
'ngRoute',
|
||||
'ng',
|
||||
'leaflet-directive'
|
||||
])
|
||||
.config(function ($routeProvider) {
|
||||
$routeProvider
|
||||
.when('/', {
|
||||
templateUrl: 'views/main.html',
|
||||
controller: 'MainCtrl',
|
||||
title: 'Willkommen'
|
||||
})
|
||||
.when('/new', {
|
||||
templateUrl: 'views/newNodeForm.html',
|
||||
controller: 'NewNodeCtrl',
|
||||
title: 'Neuen Knoten anmelden'
|
||||
})
|
||||
.when('/update', {
|
||||
templateUrl: 'views/updateNodeForm.html',
|
||||
controller: 'UpdateNodeCtrl',
|
||||
title: 'Knotendaten ändern'
|
||||
})
|
||||
.otherwise({
|
||||
redirectTo: '/'
|
||||
});
|
||||
})
|
||||
.service('Navigator', function ($location) {
|
||||
return {
|
||||
home: function () {
|
||||
$location.url('/');
|
||||
},
|
||||
newNode: function () {
|
||||
$location.url('/new');
|
||||
},
|
||||
updateNode: function () {
|
||||
$location.url('/update');
|
||||
}
|
||||
};
|
||||
})
|
||||
.run(['$location', '$rootScope', function ($location, $rootScope) {
|
||||
$rootScope.$on('$routeChangeSuccess', function (event, current) {
|
||||
$rootScope.title = current.$$route.title;
|
||||
});
|
||||
}]);
|
12
app/scripts/controllers/main.js
Normal file
12
app/scripts/controllers/main.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.controller('MainCtrl', function ($scope, Navigator) {
|
||||
$scope.newNode = function () {
|
||||
Navigator.newNode();
|
||||
};
|
||||
|
||||
$scope.updateNode = function () {
|
||||
Navigator.updateNode();
|
||||
};
|
||||
});
|
27
app/scripts/controllers/newNodeCtrl.js
Normal file
27
app/scripts/controllers/newNodeCtrl.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.controller('NewNodeCtrl', function ($scope, Navigator, NodeService, $routeParams, _) {
|
||||
$scope.node = {};
|
||||
$scope.saved = false;
|
||||
|
||||
_.each(['hostname', 'key', 'mac'], function (field) {
|
||||
var value = $routeParams[field];
|
||||
if (value) {
|
||||
$scope.node[field] = value;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.save = function (node) {
|
||||
return NodeService.createNode(node)
|
||||
.success(function (response) {
|
||||
$scope.node = response.node;
|
||||
$scope.token = response.token;
|
||||
$scope.saved = true;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
Navigator.home();
|
||||
};
|
||||
});
|
33
app/scripts/controllers/updateNodeCtrl.js
Normal file
33
app/scripts/controllers/updateNodeCtrl.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.controller('UpdateNodeCtrl', function ($scope, Navigator, NodeService) {
|
||||
$scope.node = undefined;
|
||||
$scope.token = undefined;
|
||||
$scope.saved = false;
|
||||
|
||||
$scope.hasData = function () {
|
||||
return $scope.node !== undefined;
|
||||
};
|
||||
|
||||
$scope.onSubmitToken = function (token) {
|
||||
$scope.token = token;
|
||||
return NodeService.getNode(token)
|
||||
.success(function (node) {
|
||||
$scope.node = node;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.save = function (node) {
|
||||
return NodeService.updateNode(node, $scope.token)
|
||||
.success(function (response) {
|
||||
$scope.node = response.node;
|
||||
$scope.token = response.token;
|
||||
$scope.saved = true;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
Navigator.home();
|
||||
};
|
||||
});
|
21
app/scripts/directives/help.js
Normal file
21
app/scripts/directives/help.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.directive('fHelp', function () {
|
||||
var ctrl = function ($scope) {
|
||||
$scope.showHelp = false;
|
||||
|
||||
$scope.toggleHelp = function () {
|
||||
$scope.showHelp = !$scope.showHelp;
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
'controller': ctrl,
|
||||
'restrict': 'E',
|
||||
'scope': {
|
||||
'text': '@'
|
||||
},
|
||||
'templateUrl': 'views/directives/help.html'
|
||||
};
|
||||
});
|
16
app/scripts/directives/navbar.js
Normal file
16
app/scripts/directives/navbar.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.directive('fNavbar', function (Navigator) {
|
||||
var ctrl = function ($scope) {
|
||||
$scope.goHome = function () {
|
||||
Navigator.home();
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
'controller': ctrl,
|
||||
'restrict': 'E',
|
||||
'templateUrl': 'views/directives/navbar.html'
|
||||
};
|
||||
});
|
117
app/scripts/directives/nodeForm.js
Normal file
117
app/scripts/directives/nodeForm.js
Normal file
|
@ -0,0 +1,117 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.directive('fNodeForm', function () {
|
||||
var ctrl = function ($scope, $timeout, Constraints, Validator, _) {
|
||||
angular.extend($scope, {
|
||||
center: {
|
||||
lat: 53.565278,
|
||||
lng: 10.001389,
|
||||
zoom: 10
|
||||
},
|
||||
markers: {},
|
||||
layers: {
|
||||
baselayers: {
|
||||
osm: {
|
||||
name: '',
|
||||
url: 'http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg',
|
||||
type: 'xyz',
|
||||
layerOptions: {
|
||||
subdomains: '1234',
|
||||
attribution:
|
||||
'Map data Tiles © <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> ' +
|
||||
'<img src="http://developer.mapquest.com/content/osm/mq_logo.png" />, ' +
|
||||
'Map data © OpenStreetMap contributors, CC-BY-SA'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var updateNodePosition = function (lat, lng) {
|
||||
$scope.markers.node = {
|
||||
lat: lat,
|
||||
lng: lng,
|
||||
focus: true,
|
||||
draggable: false
|
||||
};
|
||||
};
|
||||
|
||||
$scope.$on('leafletDirectiveMap.click', function (event, leaflet) {
|
||||
var lat = leaflet.leafletEvent.latlng.lat;
|
||||
var lng = leaflet.leafletEvent.latlng.lng;
|
||||
updateNodePosition(lat, lng);
|
||||
$scope.node.coords = lat + ' ' + lng;
|
||||
});
|
||||
|
||||
$scope.updateMap = function () {
|
||||
var coords = $scope.coords || '';
|
||||
coords = coords.trim();
|
||||
if (_.isEmpty(coords)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($scope.hasError('coords')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var parts = coords.split(/\s+/);
|
||||
|
||||
var lat = Number(parts[0]);
|
||||
var lng = Number(parts[1]);
|
||||
|
||||
updateNodePosition(lat, lng);
|
||||
};
|
||||
|
||||
$scope.resetCoords = function () {
|
||||
$scope.node.coords = '';
|
||||
$scope.markers = {};
|
||||
};
|
||||
|
||||
var isValid = _.reduce(Constraints.node, function (isValids, constraint, field) {
|
||||
isValids[field] = Validator.forConstraint(constraint, true);
|
||||
return isValids;
|
||||
}, {});
|
||||
var areValid = Validator.forConstraints(Constraints.node);
|
||||
|
||||
$scope.hasError = function (field) {
|
||||
var value = $scope.node[field];
|
||||
return !isValid[field](value);
|
||||
};
|
||||
|
||||
$scope.hasAnyError = function () {
|
||||
return !areValid($scope.node);
|
||||
};
|
||||
|
||||
var duplicateError = {
|
||||
hostname: 'Der Knotenname ist bereits vergeben. Bitte wähle einen anderen.',
|
||||
key: 'Für den VPN-Schlüssel gibt es bereits einen Eintrag.',
|
||||
mac: 'Für die MAC-Adresse gibt es bereits einen Eintrag.'
|
||||
};
|
||||
|
||||
$scope.onSubmit = function (node) {
|
||||
$scope.error = null;
|
||||
$scope.save(node).error(function (response, code) {
|
||||
switch (code) {
|
||||
case 409: // conflict
|
||||
$scope.error = duplicateError[response.field];
|
||||
break;
|
||||
default:
|
||||
$scope.error = 'Es ist ein Fehler aufgetreten. Versuche es später noch einmal.';
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
'controller': ctrl,
|
||||
'restrict': 'E',
|
||||
'templateUrl': 'views/directives/nodeForm.html',
|
||||
'scope': {
|
||||
'node': '=fNode',
|
||||
'save': '=fSave',
|
||||
'cancel': '=fCancel',
|
||||
'action': '@fAction'
|
||||
}
|
||||
};
|
||||
});
|
20
app/scripts/directives/nodeSaved.js
Normal file
20
app/scripts/directives/nodeSaved.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.directive('fNodeSaved', function () {
|
||||
var ctrl = function ($scope, Navigator) {
|
||||
$scope.goHome = function () {
|
||||
Navigator.home();
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
'controller': ctrl,
|
||||
'restrict': 'E',
|
||||
'scope': {
|
||||
'node': '=fNode',
|
||||
'token': '=fToken'
|
||||
},
|
||||
'templateUrl': 'views/directives/nodeSaved.html'
|
||||
};
|
||||
});
|
39
app/scripts/directives/tokenForm.js
Normal file
39
app/scripts/directives/tokenForm.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.directive('fTokenForm', function () {
|
||||
var ctrl = function ($scope, Constraints, Validator) {
|
||||
var isValid = Validator.forConstraint(Constraints.token);
|
||||
$scope.hasError = function () {
|
||||
var value = $scope.token;
|
||||
if (value === undefined) {
|
||||
return false;
|
||||
}
|
||||
return !isValid(value);
|
||||
};
|
||||
|
||||
$scope.doSubmit = function (token) {
|
||||
$scope.error = null;
|
||||
$scope.onSubmit(token)
|
||||
.error(function (response, code) {
|
||||
switch (code) {
|
||||
case 404: // not found
|
||||
$scope.error = 'Zum Token wurde kein passender Eintrag gefunden.';
|
||||
break;
|
||||
default:
|
||||
$scope.error = 'Es ist ein Fehler aufgetreten. Versuche es später noch einmal.';
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
'controller': ctrl,
|
||||
'restrict': 'E',
|
||||
'templateUrl': 'views/directives/tokenForm.html',
|
||||
'scope': {
|
||||
'onSubmit': '=fSubmit',
|
||||
'onCancel': '=fCancel'
|
||||
}
|
||||
};
|
||||
});
|
6
app/scripts/libs.js
Normal file
6
app/scripts/libs.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.factory('_', function () {
|
||||
return window._;
|
||||
});
|
18
app/scripts/services/nodeService.js
Normal file
18
app/scripts/services/nodeService.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('ffffng')
|
||||
.service('NodeService', function ($http) {
|
||||
return {
|
||||
'createNode': function (node) {
|
||||
return $http.post('/api/node', node);
|
||||
},
|
||||
|
||||
'updateNode': function (node, token) {
|
||||
return $http.put('/api/node/' + token, node);
|
||||
},
|
||||
|
||||
'getNode': function (token) {
|
||||
return $http.get('/api/node/' + token);
|
||||
}
|
||||
};
|
||||
});
|
1
app/scripts/validation/constraints.js
Symbolic link
1
app/scripts/validation/constraints.js
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../shared/validation/constraints.js
|
1
app/scripts/validation/validator.js
Symbolic link
1
app/scripts/validation/validator.js
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../shared/validation/validator.js
|
Loading…
Add table
Add a link
Reference in a new issue