summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/Test/index.html19
-rwxr-xr-x[-rw-r--r--]client/index.html39
-rw-r--r--client/js/app.js29
-rwxr-xr-x[-rw-r--r--]client/js/controllers/home/home.js327
-rw-r--r--client/js/controllers/home/machineDetails.js58
-rw-r--r--client/js/controllers/image/image.js33
-rw-r--r--client/js/controllers/image/upload.js62
-rw-r--r--client/js/controllers/login.js97
-rw-r--r--client/js/controllers/network/network.js1
-rw-r--r--client/js/controllers/status.js19
-rw-r--r--client/js/services/Compute.js279
-rw-r--r--client/js/services/Identity.js329
-rw-r--r--client/js/services/Image.js143
-rw-r--r--client/js/services/Loading.js45
-rw-r--r--client/js/services/Network.js29
-rw-r--r--client/js/services/Test.js8
-rwxr-xr-x[-rw-r--r--]client/partials/home/home.html8
-rw-r--r--client/partials/image/image.html36
-rw-r--r--client/partials/image/upload.html31
-rw-r--r--client/vendors/angularjs/angular-file-upload.min.js7
-rw-r--r--client/vendors/angularjs/angular-upload.min.js1
-rw-r--r--client/vendors/jquery/dmuploader.min.js9
22 files changed, 902 insertions, 707 deletions
diff --git a/client/Test/index.html b/client/Test/index.html
new file mode 100644
index 0000000..bff3ee1
--- /dev/null
+++ b/client/Test/index.html
@@ -0,0 +1,19 @@
+<head>
+
+ <script src="../vendors/angularjs/angular.min.js"></script>
+ <script src="../vendors/angularjs/angular-route.min.js"></script>
+ <script src="../vendors/angularjs/angular-sanitize.min.js"></script>
+ <script src="../vendors/angularjs/angular-cookies.min.js"></script>
+ <script src="../js/services/Test.js"></script>
+ <script src="../js/app.js"></script>
+</head>
+
+<body ng-app="mainApp">
+ <div ng-controller="hassan">
+ <ul>
+ <li ng-repeat="person in persons">
+ {{person.Name + ' : ' + person.Age}}
+ </li>
+ </ul>
+ </div>
+</body>
diff --git a/client/index.html b/client/index.html
index ceb4429..43659d0 100644..100755
--- a/client/index.html
+++ b/client/index.html
@@ -13,27 +13,27 @@
<link rel="stylesheet" href="./css/graph.css">
- <!--[if lt IE 9]>
- <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
- <![endif]-->
+ <!--[if lt IE 9]>
+ <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
</head>
-
-
+
+
<body>
- <!-- Overlay -->
+ <!-- Overlay -->
<div ng-include="'./partials/login.html'"></div>
<div ng-include="'./partials/home/machineDetails.html'"></div>
- <div ng-include="'./partials/loading.html'"></div>
+ <div ng-include="'./partials/loading.html'"></div>
+ <div ng-include="'./partials/image/upload.html'"></div>
-
<!-- MAIN GRID -->
<div class="container-lg">
<!-- Status bar -->
<div class="row" ng-controller="statusCtrl">
<div class="col-lg-12">
- <!-- Status bar -->
+ <!-- Status bar -->
<div ng-include="'./partials/status.html'"></div>
</div>
</div>
@@ -59,39 +59,42 @@
</div>
</div>
</div>
- </div>
+ </div>
</div>
</div>
</div>
</body>
-
-
+
+
<!-- Include JQuery -->
<script src="./vendors/jquery/jquery-2.2.0.min.js"></script>
+ <script src="./vendors/jquery/dmuploader.min.js"></script>
<!-- Include Bootstrap -->
<script src="./vendors/bootstrap/js/bootstrap.min.js"></script>
-
+
<!-- Include AngularJS and dependencies-->
<script src="./vendors/angularjs/angular.min.js"></script>
<script src="./vendors/angularjs/angular-route.min.js"></script>
<script src="./vendors/angularjs/angular-sanitize.min.js"></script>
<script src="./vendors/angularjs/angular-cookies.min.js"></script>
+ <script src="./vendors/angularjs/angular-upload.min.js"></script>
<script src="./js/app.js"></script>
-
+
<!-- Include services -->
<script src="./js/services/Identity.js"></script>
<script src="./js/services/Image.js"></script>
<script src="./js/services/Compute.js"></script>
<script src="./js/services/Loading.js"></script>
-
+
<!-- Include controller -->
<script src="./js/controllers/login.js"></script>
<script src="./js/controllers/status.js"></script>
<script src="./js/controllers/home/home.js"></script>
<script src="./js/controllers/home/machineDetails.js"></script>
<script src="./js/controllers/network/network.js"></script>
- <script src="./js/controllers/image/image.js"></script>
+ <script src="./js/controllers/image/image.js"></script>
+ <script src="./js/controllers/image/upload.js"></script>
<!-- Includes and dependencies for jointJS -->
@@ -101,10 +104,6 @@
<script src="./vendors/jointjs/lib/dagre.min.js"></script>
<script src="./vendors/jointjs/lib/graphlib.min.js"></script>
<script src="./vendors/jointjs/plugins/joint.layout.DirectedGraph.min.js"></script>
-
-
-
-
diff --git a/client/js/app.js b/client/js/app.js
index a26e0ec..4ef35b5 100644
--- a/client/js/app.js
+++ b/client/js/app.js
@@ -3,7 +3,7 @@
* The main app module instance
* @type angular.module.angular-1_3_6_L1749.moduleInstance
*/
-var mainApp=angular.module("mainApp",['ngRoute', 'ngSanitize', 'ngCookies']);
+var mainApp=angular.module("mainApp",['ngRoute', 'ngSanitize', 'ngCookies','lr.upload']);
/**
* Configure routeProvider
@@ -12,19 +12,20 @@ mainApp.config(['$routeProvider', function($routeProvider){
$routeProvider.
- when('/home',{
- templateUrl: 'partials/home/home.html',
- controller: 'homeCtrl'
- }).
- when('/network',{
- templateUrl: 'partials/network/network.html',
- controller: 'networkCtrl'
- }).
- when('/image',{
- templateUrl: 'partials/image/image.html',
- controller: 'imageCtrl'
- }).otherwise({
- redirectTo: '/'
+ when('/home',{
+ templateUrl: 'partials/home/home.html',
+ controller: 'homeCtrl'
+ }).
+ when('/network',{
+ templateUrl: 'partials/network/network.html',
+ controller: 'networkCtrl'
+ }).
+ when('/image',{
+ templateUrl: 'partials/image/image.html',
+ controller: 'imageCtrl'
+ })
+ .otherwise({
+ redirectTo: '/home'
});
}]);
diff --git a/client/js/controllers/home/home.js b/client/js/controllers/home/home.js
index 9af3ae3..f6e6b84 100644..100755
--- a/client/js/controllers/home/home.js
+++ b/client/js/controllers/home/home.js
@@ -5,129 +5,116 @@
*/
mainApp.controller('homeCtrl', [ '$scope', 'Compute', '$rootScope', 'Loading','Identity', 'Image', function ($scope, Compute, $rootScope, Loading, Identity, Image)
{
- console.log("homeCTRl");
+ console.log("test");
+ // Function to call after pull all data about machines
var callMeAfterPullData=function(data){
- $scope.machines=Compute.getData().machines;
- Loading.stop();
- }
-
- ;
- if(Compute.getData().machines == null && Identity.isAlreadyLogin()){
- Loading.start();
- Compute.pullData(callMeAfterPullData);
- }
- else{
- if(Identity.isAlreadyLogin()){
- callMeAfterPullData();
- }
- }
-
-
- Image.getImages(function(){});
-
-
- $scope.raiseShowMachineDetailsEvent=function(id){
-
- var callback=function(){
- Loading.stop();
- var data=Compute.getData();
- $rootScope.$broadcast("showMachineDetailsEvent", data.machines[id], data.axioms);
-
- }
- Loading.start();
- Compute.pullMachines(callback);
- }
-
- //adjacencyList, hard-encoded now but will be the result of a request to the server, format may change
- var vmList = {
- 'vms': [
- 'VM 1',
- 'VM 2',
- 'VM 3',
- 'VM 4',
- 'VM 5',
- 'VM 6',
- 'VM 7',
- 'VM 8',
- 'VM 9',
- 'VM 10'
- ],
- 'links': [
- ['VM 1', 'VM 2', '', ''],
- ['VM 2', 'VM 3', 'I3', 'I4'],
- ['VM 1', 'VM 3', 'I5', 'I6'],
- ['VM 2', 'VM 4', 'I5', 'I6'],
- ['VM 4', 'VM 5', 'I5', 'I6'],
- ['VM 4', 'VM 6', 'I5', 'I6'],
- ['VM 4', 'VM 1', 'I5', 'I6'],
- ['VM 7', 'VM 4', 'I5', 'I6'],
- ['VM 7', 'VM 3', 'I5', 'I6'],
- ['VM 6', 'VM 8', 'I5', 'I6'],
- ['VM 3', 'VM 9', 'I5', 'I6'],
- ['VM 3', 'VM 10', 'I5', 'I6']
- ]
+ //$scope.machines=Compute.getData().machines;
+ Loading.stop();
+ displayMachine();
};
+ var tryToRetrieveData = function () {
+ // If no data retrieve about machine and user is logged
+ if (Compute.getData().machines == null && Identity.isAlreadyLogin()) {
+ Loading.start(); // Show loading gif
+ Compute.pullData(callMeAfterPullData); // Retrieve data and call the callback
+ } else {
+ // Else if user is logged and data is already retrieve
+ // simply display data
+ if (Identity.isAlreadyLogin()) {
+ callMeAfterPullData(); // Display data
+ }
+ }
+ };
- //Custom element for inserting html
- joint.shapes.html = {};
- joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
- defaults: joint.util.deepSupplement({
- type: 'html.Element',
- attrs: {
- rect: { stroke: 'none', 'fill-opacity': 0 }
- }
- }, joint.shapes.basic.Rect.prototype.defaults)
- });
+ // On user login
+ $scope.$on('loginEvent', function () {
+ tryToRetrieveData();
+ });
+
+ // Function to call from view to display the details of a machine
+ $scope.raiseShowMachineDetailsEvent = function (id) {
+
+ // Stop loading gif and display overlay
+ var callback = function () {
+ Loading.stop();
+ var data = Compute.getData();
+
+ $rootScope.$broadcast("showMachineDetailsEvent", data.machines[id], data.axioms);
+
+ };
+ Loading.start(); // Show loading gif
+ Compute.pullMachines(callback); // Retrieve machine info and display overlay
+ };
+
+ // Try to retrieve data for the first time
+ tryToRetrieveData();
+
+ var displayMachine = function(){
+ console.log("test");
+ var machineNames = [];
+ var i = 0;
+ $.each(Compute.getData().machines, function(){
+ machineNames[i] = [this.name, this.id];
+ i++;
+ })
+ var vmList = {
+ 'vms': machineNames
+ /*'links': [
+ ['VM 1', 'VM 2', '', ''],
+ ['VM 2', 'VM 3', 'I3', 'I4'],
+ ['VM 1', 'VM 3', 'I5', 'I6'],
+ ['VM 2', 'VM 4', 'I5', 'I6'],
+ ['VM 4', 'VM 5', 'I5', 'I6'],
+ ['VM 4', 'VM 6', 'I5', 'I6'],
+ ['VM 4', 'VM 1', 'I5', 'I6'],
+ ['VM 7', 'VM 4', 'I5', 'I6'],
+ ['VM 7', 'VM 3', 'I5', 'I6'],
+ ['VM 6', 'VM 8', 'I5', 'I6'],
+ ['VM 3', 'VM 9', 'I5', 'I6'],
+ ['VM 3', 'VM 10', 'I5', 'I6']
+ ]*/
+ };
+ //Custom element for inserting html
+ joint.shapes.html = {};
+ joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
+ defaults: joint.util.deepSupplement({
+ type: 'html.Element',
+ attrs: {
+ rect: { stroke: 'none', 'fill-opacity': 0 }
+ }
+ }, joint.shapes.basic.Rect.prototype.defaults)
+ });
- //Custom view for this element
- /*joint.shapes.basic.Rect.ElementView = joint.dia.ElementView.extend({
-
- initialize: function() {
- _.bindAll(this, 'updateBox');
- joint.dia.ElementView.prototype.initialize.apply(this, arguments);
-
- this.$box = $(_.template(this.model.get('html'))());
- // Prevent paper from handling pointerdown.
- this.$box.find('input,select').on('mousedown click', function(evt) { evt.stopPropagation(); });
- // This is an example of reacting on the input change and storing the input data in the cell model.
- this.$box.find('input').on('change', _.bind(function(evt) {
- this.model.set('input', $(evt.target).val());
- }, this));
- this.$box.find('select').on('change', _.bind(function(evt) {
- this.model.set('select', $(evt.target).val());
- }, this));
- this.$box.find('select').val(this.model.get('select'));
- this.$box.on('click', function(){
- $scope.raiseShowMachineDetailsEvent();
- });
- // Update the box position whenever the underlying model changes.
- this.model.on('change', this.updateBox, this);
- // Remove the box when the model gets removed from the graph.
- this.model.on('remove', this.removeBox, this);
+ var graph = new joint.dia.Graph;
+ var paper = new joint.dia.Paper({
+ el: $('#graphHolder'),
+ width: $('#graphHolder').width(),
+ //height: test.height,
+ model: graph,
+ gridSize: 1,
+ eractive: false
+ });
+ paper.$el.css('pointer-events', 'none');
+ var cells = buildGraphFromAdjacencyList(vmList);
+
+ graph.addCells(cells);
+ var test = joint.layout.DirectedGraph.layout(graph, {
+ etLinkVertices: false,
+ //Top to bottom generation
+ ankDir: "TB",
+ odeSep: 150,
+ dgeSep: 150,
+ ankSep: 50
+ });
+
+ paper.setDimensions(test.width, test.height);
+
+ $(".Member").bind('click', function() {
+ $scope.raiseShowMachineDetailsEvent($(this).attr('model-id'));
+ });
+ }
- this.updateBox();
- },
- render: function() {
- joint.dia.ElementView.prototype.render.apply(this, arguments);
- this.paper.$el.prepend(this.$box);
- this.updateBox();
- return this;
- },
- updateBox: function() {
- // Set the position and dimension of the box so that it covers the JointJS element.
- var bbox = this.model.getBBox();
- // Example of updating the HTML with a data stored in the cell model.
- this.$box.find('label').text(this.model.get('name'));
- this.$box.find('span').text(this.model.get('select'));
- this.$box.css({ width: bbox.width, height: bbox.height, left: bbox.x, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)' });
- },
- removeBox: function(evt) {
- this.$box.remove();
- }
- });
- */
-
//Read the adjacencyList and build the elements and the links according to it
function buildGraphFromAdjacencyList(adjacencyList) {
@@ -137,11 +124,9 @@ mainApp.controller('homeCtrl', [ '$scope', 'Compute', '$rootScope', 'Loading','I
_.each(adjacencyList['vms'], function(vm) {
elements.push(makeElement(vm));
});
- console.log(elements);
_.each(adjacencyList['links'], function(link) {
links.push(makeLink(link[0], link[1] , link[2], link[3]));
});
- console.log(links);
// Links must be added after all the elements. This is because when the links
// are added to the graph, link source/target
// elements must be in the graph already.
@@ -162,7 +147,8 @@ mainApp.controller('homeCtrl', [ '$scope', 'Compute', '$rootScope', 'Loading','I
}
//Return a new element
- function makeElement(label) {
+ function makeElement(vm) {
+ var label = vm[0];
var maxLineLength = _.max(label.split('\n'), function(l) { return l.length; }).length;
@@ -171,83 +157,30 @@ mainApp.controller('homeCtrl', [ '$scope', 'Compute', '$rootScope', 'Loading','I
// an approximation of the monospace font letter width.
var width = 130;
var height = 80;
-
- /*return new joint.shapes.html.Element({
- id: label,
- name: label,
- size: { width: width, height: height },
-
- html: [
- '<div class="html-element">',
- '<img src="./images/ON.png">',
- '<label></label>',
- '<input type="image" src="./images/gear.png" class="config"></button>',
- '</div>'
- ].join(''),
-
- attrs: {
- rect: {
- fill: '#FE854F',
- width: width,
- height: height,
- rx: 5,
- ry: 5,
- stroke: 'none'
- }
- }
- });*/
- return new joint.shapes.org.Member({
- id: label,
- position: { x: 0, y: 0 },
- attrs: {
- '.card': { fill: 'blue', stroke: 'none'},
- image: { 'xlink:href': './images/ON.png', opacity: 0.7 },
- //'.rank': { text: rank, fill: textColor, 'word-spacing': '-5px', 'letter-spacing': 0},
- '.name': { text: label, fill: 'white', 'font-size': 13, 'font-family': 'Arial', 'letter-spacing': 0 }
+ var data = Compute.getData();
+ console.log(data.machines[vm[1]]);
+ if(data.machines[vm[1]].status == "ACTIVE"){
+ return new joint.shapes.org.Member({
+ id: vm[1],
+ position: { x: 0, y: 0 },
+ attrs: {
+ '.card': { fill: 'blue', stroke: 'none'},
+ image: { 'xlink:href': './images/ON.png', opacity: 0.7 },
+ //'.rank': { text: rank, fill: textColor, 'word-spacing': '-5px', 'letter-spacing': 0},
+ '.name': { text: label, fill: 'white', 'font-size': 13, 'font-family': 'Arial', 'letter-spacing': 0 }
+ }
+ });
+ }else{
+ return new joint.shapes.org.Member({
+ id: vm[1],
+ position: { x: 0, y: 0 },
+ attrs: {
+ '.card': { fill: 'blue', stroke: 'none'},
+ image: { 'xlink:href': './images/OFF.png', opacity: 0.7 },
+ //'.rank': { text: rank, fill: textColor, 'word-spacing': '-5px', 'letter-spacing': 0},
+ '.name': { text: label, fill: 'white', 'font-size': 13, 'font-family': 'Arial', 'letter-spacing': 0 }
+ }
+ });
}
- });
}
-
- var graph = new joint.dia.Graph;
- var paper = new joint.dia.Paper({
- el: $('#graphHolder'),
- width: $('#graphHolder').width(),
- //height: test.height,
- model: graph,
- gridSize: 1,
- interactive: false
- });
- paper.$el.css('pointer-events', 'none');
- var cells = buildGraphFromAdjacencyList(vmList);
- console.log(cells);
- /*graph.resetCells(cells);
- joint.layout.DirectedGraph.layout(graph, {
- setLinkVertices: false,
- //Top to bottom generation
- rankDir: "TB",
- nodeSep: 150,
- edgeSep: 150,
- rankSep: 150
- });*/
- graph.addCells(cells);
- var test = joint.layout.DirectedGraph.layout(graph, {
- setLinkVertices: false,
- //Top to bottom generation
- rankDir: "TB",
- nodeSep: 150,
- edgeSep: 150,
- rankSep: 50
- });
- console.log(test);
-
- paper.setDimensions(test.width, test.height);
-
- $(".Member").bind('click', function() {
- console.log("Click");
- $scope.raiseShowMachineDetailsEvent();
- });
-
-
-
-
}]);
diff --git a/client/js/controllers/home/machineDetails.js b/client/js/controllers/home/machineDetails.js
index c015eaa..9c8c602 100644
--- a/client/js/controllers/home/machineDetails.js
+++ b/client/js/controllers/home/machineDetails.js
@@ -3,41 +3,43 @@
*
* @param {$scope} $scope The $scope service from angular
*/
-mainApp.controller('machineDetailsCtrl', [ '$scope', 'Compute', '$rootScope', '$timeout', function ($scope, Compute, $rootScope, $timeout)
-{
+mainApp.controller('machineDetailsCtrl', ['$scope', 'Compute', '$rootScope', '$timeout', 'Identity', function ($scope, Compute, $rootScope, $timeout, Identity)
+ {
- // Init scope
- $scope.machine={};
- $scope.machineIsStarting=false; // For loading icon
+ // Init scope
+ $scope.machine = {};
+ $scope.machineIsStarting = false; // For loading icon
- $scope.$on('showMachineDetailsEvent', function(eventName ,machine, axioms){
- $scope.machine=machine;
- $scope.axioms=axioms;
- $('#machineDetailsModal').modal({backdrop: false, keyboard: true});
- });
+ // When we need to show details of machine
+ $scope.$on('showMachineDetailsEvent', function (eventName, machine, axioms) {
+ $scope.machine = machine;
+ $scope.axioms = axioms;
+ $('#machineDetailsModal').modal({backdrop: false, keyboard: true});
+ });
+ // Try to stop or start a machine
+ $scope.toggleMachineState = function () {
+ // Display gif
+ $scope.machineIsStarting = true;
- $scope.toggleMachineState=function(){
- // Display gif
- $scope.machineIsStarting=true;
+ // Fake timeout
+ $timeout(function () {
+ $scope.machineIsStarting = false;
+ }, 3000);
+ $timeout(function () {
+ $scope.machine.online = !$scope.machine.online;
- // Fake timeout
- $timeout(function(){
- $scope.machineIsStarting=false;
- }, 3000);
- $timeout(function(){
- $scope.machine.online=!$scope.machine.online;
+ }, 3000);
- }, 3000);
-
- };
+ };
- $scope.applyModifications=function(){
- //Todo
- }
-
+ // Apply modifications
+ $scope.applyModifications = function () {
+ //Todo
+ };
-
-}]);
+
+
+ }]);
diff --git a/client/js/controllers/image/image.js b/client/js/controllers/image/image.js
index e298fcc..d0578d7 100644
--- a/client/js/controllers/image/image.js
+++ b/client/js/controllers/image/image.js
@@ -3,19 +3,22 @@
*
* @param {$scope} $scope The $scope service from angular
*/
-mainApp.controller('imageCtrl', ['$scope', 'Image', 'Loading', function ($scope, Image, Loading)
-{
- var callbackTest=function(){
- $scope.images=Image.getData().images;
- Loading.stop();
- };
+mainApp.controller('imageCtrl', ['$scope', 'Image', 'Loading', 'Identity', function ($scope, Image, Loading, Identity)
+ {
- if(Image.getData().images==null){
- Loading.start();
- Image.getImages(callbackTest);
- }
- else{
- callbackTest();
- }
-
-}]);
+ // Update view
+ var callMeAfterGetImage = function () {
+ $scope.images = Image.getData().images;
+ Loading.stop();
+ };
+
+ // If user is login try to retrieve data
+ if (Identity.isAlreadyLogin()) {
+ if (Image.getData().images == null) {
+ Loading.start();
+ Image.getImages(callMeAfterGetImage);
+ } else {
+ callMeAfterGetImage();
+ }
+ }
+ }]);
diff --git a/client/js/controllers/image/upload.js b/client/js/controllers/image/upload.js
new file mode 100644
index 0000000..6737269
--- /dev/null
+++ b/client/js/controllers/image/upload.js
@@ -0,0 +1,62 @@
+/**
+ * The image controller
+ *
+ * @param {$scope} $scope The $scope service from angular
+ */
+mainApp.controller('uploadImageCtrl', ['$scope', 'Image', 'Loading', 'Identity', 'upload', function ($scope, Image, Loading, Identity, upload)
+ {
+ /*$scope.uploader = new FileUploader({
+ "token" : Identity.getToken(),
+ "task" : "image",
+ 'action':'uploadImage',
+ 'id':'6564'
+ });
+ $scope.uploader.url='../server/index.php'
+ $scope.uploader.alias='file_name'
+ $scope.uploader.formData={
+ "token" : Identity.getToken(),
+ "task" : "image",
+ 'action':'uploadImage',
+ 'id':'6564'
+ }
+ */
+
+ $scope.doUpload = function () {
+ console.log($('#imageToUpload').prop('files')[0]);
+ Image.uploadImage($('#imageToUpload').prop('files')[0], function () {
+ alert("done")
+ })
+ /*$("#drop-area-div").dmUploader({
+ extraData: {
+ "token" : Identity.getToken(),
+ "task" : "image",
+ 'action':'uploadImage',
+ 'id':'6564'},
+ url:"../server/index.php"
+ });
+ */
+
+ /*upload({
+ url: '../server/index.php',
+ method: 'POST',
+ data: {
+ "token" : Identity.getToken(),
+ "task" : "image",
+ 'action':'uploadImage',
+ 'id':'6564',
+ "file_name": $scope.myFile, // a jqLite type="file" element, upload() will extract all the files from the input and put them into the FormData object before sending.
+ }
+ }).then(
+ function (response) {
+ console.log(response.data); // will output whatever you choose to return from the server on a successful upload
+ },
+ function (response) {
+ console.error(response); // Will return if status code is above 200 and lower than 300, same as $http
+ }
+ );*/
+
+
+ };
+
+ $scope.token = Identity.getToken();
+ }]);
diff --git a/client/js/controllers/login.js b/client/js/controllers/login.js
index 63cb6d1..4a0de42 100644
--- a/client/js/controllers/login.js
+++ b/client/js/controllers/login.js
@@ -5,62 +5,63 @@
* @param {$sce} $sce The $sce angular service
* @param {$http} $http The $http angular service
* @param {Identity} The Identity service
-
+
*/
-mainApp.controller('loginCtrl', ['$scope','$sce','Identity', function ($scope,$sce, Identity)
-{
- // Check for login and define default states
- if(!Identity.isAlreadyLogin()){
- $('#loginModal').modal({backdrop: 'static', keyboard: false});
- }
+mainApp.controller('loginCtrl', ['$scope', '$sce', 'Identity', '$rootScope', function ($scope, $sce, Identity, $rootScope)
+ {
+ // Check for login and define default states
+ if (!Identity.isAlreadyLogin()) {
+ $('#loginModal').modal({backdrop: 'static', keyboard: false});
+ }
- // Manager logout event
- $scope.$on('logoutEvent', function(){
- $('#loginModal').modal({backdrop: 'static', keyboard: false});
- });
+ // Manager logout event
+ $scope.$on('logoutEvent', function () {
+ $('#loginModal').modal({backdrop: 'static', keyboard: false});
+ });
-
- // Hide loading button and message alert
- $('#loadingLoginButton').hide();
- $('#failedToLoginAlert').hide();
-
- // Defined function for login
- $scope.loginAction=function(){
-
- // Begin login state for template
- $('#loginButton').hide();
- $('#loadingLoginButton').show();
+ // Hide loading button and message alert
+ $('#loadingLoginButton').hide();
$('#failedToLoginAlert').hide();
- // Get data from templates
- var username=$("#loginFormUsername").val();
- var password=$("#loginFormPassword").val();
- var projectname=$("#loginFormProjectname").val();
- // Function to call to handle result
- var responseCallback=function(response){
+ // Defined function for login
+ $scope.loginAction = function () {
+
+ // Begin login state for template
+ $('#loginButton').hide();
+ $('#loadingLoginButton').show();
+ $('#failedToLoginAlert').hide();
+
+ // Get data from templates
+ var username = $("#loginFormUsername").val();
+ var password = $("#loginFormPassword").val();
+ var projectname = $("#loginFormProjectname").val();
+
+ // Function to call to handle result
+ var responseCallback = function (response) {
+
+ if (response.status !== 0) {
+ // Set reason of fail
+ $scope.failReason = response.failReason;
+
+ // Display the error
+ $('#failedToLoginAlert').show();
+ } else {
+ // Else the user is online !
+ $('#loginModal').modal('hide');
+ // Send login event
+ $rootScope.$broadcast("loginEvent");
+ }
- if(response.status!==0){
- // Set reason of fail
- $scope.failReason=response.failReason;
+ // Reset button state
+ $('#loginButton').show();
+ $('#loadingLoginButton').hide();
+ };
- // Display the error
- $('#failedToLoginAlert').show();
- }
- else {
- // Else the user is online !
- $('#loginModal').modal('hide');
- }
+ // Try to login
+ Identity.login(username, password, projectname, responseCallback);
+ };
- // Reset button state
- $('#loginButton').show();
- $('#loadingLoginButton').hide();
- }
-
- // Try to login
- Identity.login(username, password, projectname, responseCallback);
- };
-
-}]);
+ }]);
diff --git a/client/js/controllers/network/network.js b/client/js/controllers/network/network.js
index 7264aec..f600f83 100644
--- a/client/js/controllers/network/network.js
+++ b/client/js/controllers/network/network.js
@@ -5,4 +5,5 @@
*/
mainApp.controller('networkCtrl', function ($scope)
{
+
}); \ No newline at end of file
diff --git a/client/js/controllers/status.js b/client/js/controllers/status.js
index 6f398ad..c3e634b 100644
--- a/client/js/controllers/status.js
+++ b/client/js/controllers/status.js
@@ -6,15 +6,14 @@
* @param {$scope} $scope The $scope service from angular
* @param {Identity} The Identity service
*/
-mainApp.controller('statusCtrl', ['$scope','Identity', '$rootScope', function ($scope, Identity, $rootScope)
-{
+mainApp.controller('statusCtrl', ['$scope', 'Identity', '$rootScope', function ($scope, Identity, $rootScope)
+ {
+ // Give profile to model
+ $scope.profile = Identity.getProfile();
- // Give profile to model
- $scope.profile=Identity.getProfile();
-
- // Function to logout
- $scope.logout=function(){
- Identity.logout();
- };
+ // Function to logout
+ $scope.logout = function () {
+ Identity.logout();
+ };
-}]);
+ }]);
diff --git a/client/js/services/Compute.js b/client/js/services/Compute.js
index 36ddc16..5e95f22 100644
--- a/client/js/services/Compute.js
+++ b/client/js/services/Compute.js
@@ -1,141 +1,140 @@
-mainApp.factory('Compute',[ '$http', 'Identity', function($http, Identity){
-
-
- // Init data
- var data={};
- data.machines=null;
- data.axioms={} // Contain static data
- data.axioms.ram=[128,512,1024,2048,4096];
- data.axioms.disk=[1,2,5,10,25,50,100,150,200]
- data.axioms.images={}; // Retrieve after
-
-
- /**
- * Parse pullMachines answer
- * @param {response} the server response
- * @param {boolean} false if the request as been send true else
- * @return {requestParserResult} the result of parsing
- */
- var parsePullMachinesAnswer=function(response, failedToSendRequest){
-
- // Defined return object
- var requestParserResult={};
- requestParserResult.status=1;
- requestParserResult.failReason=null;
-
-
- if (typeof response.data.Servers !== 'undefined') {
- // Set status code
- requestParserResult.status=0;
- data.machines=response.data.Servers;
-
- }
- else if(failedToSendRequest){
- requestParserResult.failReason="Failed to send request";
- }
- else{
- requestParserResult.failReason="Error";
- }
- return requestParserResult;
- };
-
-
- /**
- * Retrieve machine list
- * @param {callback} function to call after request complete
- */
- var pullMachines=function(callback){
- // Send listServers request
- var result=$http.post('../server/index.php',
- $.param({"token" : Identity.getToken(), "task" : "compute", "action":"listServers"}));
-
- // Wait and handle the response
- result.then(function (response){
- callback(parsePullMachinesAnswer(response, false));
- },function(response){
- callback(parsePullMachinesAnswer(response, true));
- });
- };
-
-
- /**
- * Parse pullImages answer
- * @param {response} the server response
- * @param {boolean} false if the request as been send true else
- * @return {requestParserResult} the result of parsing
- */
- var parsePullImagesAnswer=function(response, failedToSendRequest){
-
- // Defined return object
- var requestParserResult={};
- requestParserResult.status=1;
- requestParserResult.failReason=null;
-
-
- if (typeof response.data.Images !== 'undefined') {
- // Set status code
- requestParserResult.status=0;
- data.axioms.images=response.data.Images;
- }
- else if(failedToSendRequest){
- requestParserResult.failReason="Failed to send request";
- }
- else{
- requestParserResult.failReason="Error";
- }
- return requestParserResult;
- };
-
-
-
-
- /**
- * Retrieve machine list
- * @param {callback} function to call after request complete
- */
- var pullImages=function(callback){
- // Send listServers request
- var result=$http.post('../server/index.php',
- $.param({"token" : Identity.getToken(), "task" : "compute", "action":"listImages"}));
-
- // Wait and handle the response
- result.then(function (response){
- callback(parsePullImagesAnswer(response, false));
- },function(response){
- callback(parsePullImagesAnswer(response, true));
- });
- };
-
-
- /**
- * Retrieve all data
- * @param {callback} function to call after request complete
- */
- var pullData=function(callback){
- var nextFunction=function(response){
- if(response.status==0){
- pullMachines(callback);
- }
- }
- pullImages(nextFunction);
- }
-
-
- /**
- * Get Data
- * @return {data} return the data object
- */
- var getData=function(){
- return data;
- }
-
- // Return services objects
- return {
- pullMachines: pullMachines,
- pullData: pullData,
- getData: getData
- };
-
-
-}]);
+mainApp.factory('Compute', ['$http', 'Identity', function ($http, Identity) {
+
+
+ // Init data
+ var data = {};
+ data.machines = null;
+ data.axioms = {} // Contain static data
+ data.axioms.ram = [128, 512, 1024, 2048, 4096];
+ data.axioms.disk = [1, 2, 5, 10, 25, 50, 100, 150, 200]
+ data.axioms.images = {}; // Retrieve after
+
+
+ /**
+ * Parse pullMachines answer
+ * @param {response} the server response
+ * @param {boolean} false if the request as been send true else
+ * @return {requestParserResult} the result of parsing
+ */
+ var parsePullMachinesAnswer = function (response, failedToSendRequest) {
+
+ // Defined return object
+ var requestParserResult = {};
+ requestParserResult.status = 1;
+ requestParserResult.failReason = null;
+
+
+ if (typeof response.data.Servers !== 'undefined') {
+ // Set status code
+ requestParserResult.status = 0;
+ data.machines = response.data.Servers;
+
+ } else if (failedToSendRequest) {
+ requestParserResult.failReason = "Failed to send PullMachine request";
+ } else {
+ requestParserResult.failReason = "Error";
+ }
+ return requestParserResult;
+ };
+
+
+ /**
+ * Retrieve machine list
+ * @param {callback} function to call after request complete
+ */
+ var pullMachines = function (callback) {
+ // Send listServers request
+ var result = $http.post('../server/index.php',
+ $.param({"token": Identity.getToken(), "task": "compute", "action": "listServers"}));
+
+ // Wait and handle the response
+ result.then(function (response) {
+ callback(parsePullMachinesAnswer(response, false));
+ }, function (response) {
+ callback(parsePullMachinesAnswer(response, true));
+ });
+ };
+
+
+ /**
+ * Parse pullImages answer
+ * @param {response} the server response
+ * @param {boolean} false if the request as been send true else
+ * @return {requestParserResult} the result of parsing
+ */
+ var parsePullImagesAnswer = function (response, failedToSendRequest) {
+
+ // Defined return object
+ var requestParserResult = {};
+ requestParserResult.status = 1;
+ requestParserResult.failReason = null;
+
+
+ if (typeof response.data.Images !== 'undefined') {
+ // Set status code
+ requestParserResult.status = 0;
+ data.axioms.images = response.data.Images;
+ } else if (failedToSendRequest) {
+ requestParserResult.failReason = "Failed to send PullImage request";
+ } else {
+ requestParserResult.failReason = "Error";
+ }
+ return requestParserResult;
+ };
+
+
+
+
+ /**
+ * Retrieve machine list
+ * @param {callback} function to call after request complete
+ */
+ var pullImages = function (callback) {
+ // Send listServers request
+ var result = $http.post('../server/index.php',
+ $.param({"token": Identity.getToken(), "task": "compute", "action": "listImages"}));
+
+ // Wait and handle the response
+ result.then(function (response) {
+ callback(parsePullImagesAnswer(response, false));
+ }, function (response) {
+
+ callback(parsePullImagesAnswer(response, true));
+ });
+ };
+
+
+ /**
+ * Retrieve all data
+ * @param {callback} function to call after request complete
+ */
+ var pullData = function (callback) {
+ var nextFunction = function (response) {
+ if (response.status == 0) {
+ pullMachines(callback);
+ } else {
+ callback(response);
+ }
+ };
+ pullImages(nextFunction);
+ };
+
+
+ /**
+ * Get Data
+ * @return {data} return the data object
+ */
+ var getData = function () {
+ return data;
+ };
+
+ // Return services objects
+ return {
+ pullMachines: pullMachines,
+ pullData: pullData,
+ getData: getData
+ };
+
+
+ }]);
diff --git a/client/js/services/Identity.js b/client/js/services/Identity.js
index db93e97..17678ed 100644
--- a/client/js/services/Identity.js
+++ b/client/js/services/Identity.js
@@ -1,163 +1,168 @@
-mainApp.factory('Identity',[ '$http', '$cookies', function($http, $cookies){
-
- /* Create profile structure to store informations
- * about current session
- */
- var profile={};
- profile.username=null;
- profile.projectname=null;
- var token=null;
-
-
- /*
- * @returns {boolean} Return true if a cookie is found (and load it in profile) false else
- */
- var isAlreadyLogin=function(){
-
- // Load cookies
- var profileInCookie=$cookies.getObject('profile');
- var tokenPart_0InCookie=$cookies.getObject('token.part_0');
- var tokenPart_1InCookie=$cookies.getObject('token.part_1');
-
-
- // Check if cookie is defined
- if(typeof profileInCookie !== 'undefined'
- && typeof tokenPart_0InCookie !== 'undefined'
- && typeof tokenPart_1InCookie !== 'undefined'
- ){
-
- // If yes, put it into variables
- angular.extend(profile, profileInCookie);
- token=tokenPart_0InCookie+tokenPart_1InCookie;
-
- // Return I'm Login
- return true;
- }
-
- // Return I'm not Login
- return false;
- }
-
-
-
- /*
- * Destroy profile cookies
- */
- var logout=function(){
- $cookies.remove('profile');
- $cookies.remove('token.part_0');
- $cookies.remove('token.part_1');
- token=null;
- profile.username=null;
- profile.projectname=null;
-
- // Reload Page
- location.reload();
- }
-
-
- /**
- *
- * @param {string} response The response to parse
- * @param {boolean} to check if the request is send or not
- * @returns {requestParserResult} Formated data
- */
- var parseLoginAnswer=function(response, failedToSendRequest){
-
- // Defined return object
- var requestParserResult={};
- requestParserResult.status=1;
- requestParserResult.failReason=null;
-
- if (typeof response.data.token !== 'undefined') {
- // Set status code
- requestParserResult.status=0;
-
- // Find the middle of the token to split it
- var middle=parseInt(response.data.token.length/2);
-
- // Create expire date (cookie expire in 55 mins)
- var expireDate=new Date();
- expireDate.setMinutes(expireDate.getMinutes()+55);
-
- // Save profile
- $cookies.putObject('profile', profile, {'expires': expireDate});
- // Save first part of token
- $cookies.putObject('token.part_0', response.data.token.substring(0, middle), {'expires': expireDate});
- // Save second part of token
- $cookies.putObject('token.part_1', response.data.token.substring(middle, response.data.token.length), {'expires': expireDate});
-
- // Put token in var
- token=response.data.token;
-
- }
- else if(failedToSendRequest){
- requestParserResult.failReason="Failed to send request";
- }
- else{
- requestParserResult.failReason="Please check your username, password and project name !";
- }
-
-
- return requestParserResult;
- };
-
-
- /**
- * Function to connect to OpenStack
- *
- * @param {object} $http Angular $http service
- * @param {string} username The user name
- * @param {string} password The user password
- * @param {string} projectname The user project name
- * @param {function} function to call when data is avalaible
- */
- var login=function(username, password,projectname,callback){
-
- // Set profile information (early)
- profile.username=username;
- profile.projectname=projectname;
-
- var result=$http.post('../server/index.php',
- $.param({"task" : "Authenticate", "user" : username, "password" : password, "project" : projectname}));
-
- // Wait and handle the response
- result.then(function (response){
- callback(parseLoginAnswer(response, false));
- },function(response){
- callback(parseLoginAnswer(response, true));
- });
- };
-
-
-
-
-
- /*
- * Get the profile
- */
- var getProfile=function(){
- return profile;
- }
-
- /*
- * Get the token
- */
- var getToken=function(){
- return token;
- }
-
-
-
- // Return services objects
- return {
- login: login,
- getProfile: getProfile,
- isAlreadyLogin: isAlreadyLogin,
- logout:logout,
- getToken:getToken
- };
-
-
-}]);
+mainApp.factory('Identity', ['$http', '$cookies', '$rootScope', function ($http, $cookies, $rootScope) {
+
+ /* Create profile structure to store informations
+ * about current session
+ */
+ var profile = {};
+ profile.username = null;
+ profile.projectname = null;
+ var token = null;
+
+
+ /*
+ * @returns {boolean} Return true if a cookie is found (and load it in profile) false else
+ */
+ var isAlreadyLogin = function () {
+
+ // Load cookies
+ var profileInCookie = $cookies.getObject('profile');
+ var tokenPart_0InCookie = $cookies.getObject('token.part_0');
+ var tokenPart_1InCookie = $cookies.getObject('token.part_1');
+
+
+ // Check if cookie is defined
+ if (typeof profileInCookie !== 'undefined'
+ && typeof tokenPart_0InCookie !== 'undefined'
+ && typeof tokenPart_1InCookie !== 'undefined'
+ ) {
+
+ //if(token!==null){
+ // If yes, put it into variables
+ angular.extend(profile, profileInCookie);
+ token = tokenPart_0InCookie + tokenPart_1InCookie;
+ //}
+
+ // Return I'm Login
+ return true;
+ }
+
+ // Show the login overlay
+ $rootScope.$broadcast("logoutEvent");
+
+ // Return I'm not Login
+ return false;
+ };
+
+
+
+ /*
+ * Destroy profile cookies
+ */
+ var logout = function () {
+ $cookies.remove('profile');
+ $cookies.remove('token.part_0');
+ $cookies.remove('token.part_1');
+ token = null;
+ profile.username = null;
+ profile.projectname = null;
+
+ // Reload Page
+ //location.reload();
+ $rootScope.$broadcast("logoutEvent");
+
+ };
+
+
+ /**
+ *
+ * @param {string} response The response to parse
+ * @param {boolean} to check if the request is send or not
+ * @returns {requestParserResult} Formated data
+ */
+ var parseLoginAnswer = function (response, failedToSendRequest) {
+
+ // Defined return object
+ var requestParserResult = {};
+ requestParserResult.status = 1;
+ requestParserResult.failReason = null;
+
+ if (typeof response.data.token !== 'undefined') {
+ // Set status code
+ requestParserResult.status = 0;
+
+ // Find the middle of the token to split it
+ var middle = parseInt(response.data.token.length / 2);
+
+ // Create expire date (cookie expire in 55 mins)
+ var expireDate = new Date();
+ expireDate.setMinutes(expireDate.getMinutes() + 55);
+
+ // Save profile
+ $cookies.putObject('profile', profile, {'expires': expireDate});
+ // Save first part of token
+ $cookies.putObject('token.part_0', response.data.token.substring(0, middle), {'expires': expireDate});
+ // Save second part of token
+ $cookies.putObject('token.part_1', response.data.token.substring(middle, response.data.token.length), {'expires': expireDate});
+
+ // Put token in var
+ token = response.data.token;
+
+ } else if (failedToSendRequest) {
+ requestParserResult.failReason = "Failed to send request";
+ } else {
+ requestParserResult.failReason = "Please check your username, password and project name !";
+ }
+
+
+ return requestParserResult;
+ };
+
+
+ /**
+ * Function to connect to OpenStack
+ *
+ * @param {object} $http Angular $http service
+ * @param {string} username The user name
+ * @param {string} password The user password
+ * @param {string} projectname The user project name
+ * @param {function} function to call when data is avalaible
+ */
+ var login = function (username, password, projectname, callback) {
+
+ // Set profile information (early)
+ profile.username = username;
+ profile.projectname = projectname;
+
+ var result = $http.post('../server/index.php',
+ $.param({"task": "Authenticate", "user": username, "password": password, "project": projectname}));
+
+ // Wait and handle the response
+ result.then(function (response) {
+ callback(parseLoginAnswer(response, false));
+ }, function (response) {
+ callback(parseLoginAnswer(response, true));
+ });
+ };
+
+
+
+
+
+ /*
+ * Get the profile
+ */
+ var getProfile = function () {
+ return profile;
+ };
+
+ /*
+ * Get the token
+ */
+ var getToken = function () {
+ return token;
+ };
+
+
+
+ // Return services objects
+ return {
+ login: login,
+ getProfile: getProfile,
+ isAlreadyLogin: isAlreadyLogin,
+ logout: logout,
+ getToken: getToken
+ };
+
+
+ }]);
diff --git a/client/js/services/Image.js b/client/js/services/Image.js
index 2e8c56f..795f85e 100644
--- a/client/js/services/Image.js
+++ b/client/js/services/Image.js
@@ -1,59 +1,114 @@
-mainApp.factory('Image',[ '$http', 'Identity', function($http, Identity){
+mainApp.factory('Image', ['$http', 'Identity', function ($http, Identity) {
- var data={};
- data.images=null;
+ // Data object
+ var data = {};
+ data.images = null; // Images
+ /**
+ * Parse uploadImage anwser
+ * @param {type} response
+ * @param {type} failedToSendRequest
+ * @returns {Image_L2.parseUploadImageAnswer.requestParserResult}
+ */
+ var parseUploadImageAnswer = function (response, failedToSendRequest) {
- var parseUploadImageAnswer=function(response, failedToSendRequest){
+ // Defined return object
+ var requestParserResult = {};
+ requestParserResult.status = 1;
+ requestParserResult.failReason = null;
- // Defined return object
- var requestParserResult={};
- requestParserResult.status=1;
- requestParserResult.failReason=null;
-
- if (typeof response.data.Images !== 'undefined') {
- // Set status code
- requestParserResult.status=0;
- data.images=response.data.Images;
+ if (typeof response.data.Images !== 'undefined') {
+ // Set status code
+ requestParserResult.status = 0;
+ data.images = response.data.Images;
- }
- else if(failedToSendRequest){
- requestParserResult.failReason="Failed to send request";
- }
- else{
- requestParserResult.failReason="Error";
- }
- return requestParserResult;
- };
+ } else if (failedToSendRequest) {
+ requestParserResult.failReason = "Failed to send request";
+ } else {
+ requestParserResult.failReason = "Error";
+ }
+ return requestParserResult;
+ };
- var getImages=function(callback){
+ /**
+ * Get images
+ * @param {type} callback
+ * @returns {undefined}
+ */
+ var getImages = function (callback) {
- var result=$http.post('../server/index.php',
- $.param({"token" : Identity.getToken(), "task" : "image", 'action':'listImage'}));
+ var result = $http.post('../server/index.php',
+ $.param({"token": Identity.getToken(), "task": "image", 'action': 'listImage'}));
- // Wait and handle the response
- result.then(function (response){
- callback(parseUploadImageAnswer(response, false));
- },function(response){
- callback(parseUploadImageAnswer(response, true));
- });
+ // Wait and handle the response
+ result.then(function (response) {
+ callback(parseUploadImageAnswer(response, false));
+ }, function (response) {
+ callback(parseUploadImageAnswer(response, true));
+ });
-
- };
+ };
- var getData=function(response){
- return data;
- };
-
- // Return services objects
- return {
- getImages:getImages,
- getData:getData
- };
+ /**
+ * Upload an image
+ * @param {type} fileToUpload
+ * @param {type} callback
+ * @returns {undefined}
+ */
+ var uploadImage = function (fileToUpload, callback) {
+ var form_data = new FormData();
+ form_data.append('file', fileToUpload);
+ console.log(fileToUpload);
+ form_data.append("task", "image");
+ form_data.append("token", Identity.getToken());
+ form_data.append('action', "uploadImage");
+ form_data.append('id', '6564');
+ form_data.append('file_name', fileToUpload);
-
-}]);
+ $.ajax({
+ url: "../server/index.php", // Url to which the request is send
+ type: "POST", // Type of request to be send, called as method
+ data: form_data, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
+ file_name: fileToUpload,
+ token: Identity.getToken(),
+ task: "image",
+ action: 'uploadImage',
+ id: '6564',
+ contentType: false, // The content type used when sending data to the server.
+ cache: false, // To unable request pages to be cached
+ processData: false, // To send DOMDocument or non processed data file it is set to false
+ success: function (data) // A function to be called if request succeeds
+ {
+ alert("success");
+ }
+ });
+
+ //var result=$http.post('../server/index.php',
+ // $.param({"token" : Identity.getToken(), "task" : "image", 'action':'uploadImage', 'file_name':form_data, 'id':'6564'}));
+
+ // Wait and handle the response
+ /* result.then(function (response){
+ callback(parseUploadImageAnswer(response, false));
+ },function(response){
+ callback(parseUploadImageAnswer(response, true));
+ });*/
+ };
+
+
+ var getData = function (response) {
+ return data;
+ };
+
+ // Return services objects
+ return {
+ getImages: getImages,
+ getData: getData,
+ uploadImage: uploadImage
+ };
+
+
+ }]);
diff --git a/client/js/services/Loading.js b/client/js/services/Loading.js
index db06194..7ea2b42 100644
--- a/client/js/services/Loading.js
+++ b/client/js/services/Loading.js
@@ -1,23 +1,26 @@
+/**
+ * Loading service
+ * @param {type} param1
+ * @param {type} param2
+ */
+mainApp.factory('Loading', [function () {
+ /**
+ * Display Loading modal
+ */
+ var start = function () {
+ $('#loadingModal').modal({backdrop: 'static', keyboard: false});
+ };
-mainApp.factory('Loading',[ function(){
- /**
- * Display Loading modal
- */
- var start=function(){
- $('#loadingModal').modal({backdrop: 'static', keyboard: false});
- };
+ /**
+ * Hide Loading modal
+ */
+ var stop = function () {
+ $('#loadingModal').modal('hide');
+ };
- /**
- * Hide Loading modal
- */
- var stop=function(){
- $('#loadingModal').modal('hide');
- }
-
-
- // Service returns
- return {
- start:start,
- stop:stop
- };
-}]);
+ // Service returns
+ return {
+ start: start,
+ stop: stop
+ };
+ }]);
diff --git a/client/js/services/Network.js b/client/js/services/Network.js
new file mode 100644
index 0000000..a0cd5a4
--- /dev/null
+++ b/client/js/services/Network.js
@@ -0,0 +1,29 @@
+
+mainApp.factory('Network', ['$http', 'Identity', function ($http, Identity) {
+
+ // Data object
+ var data = {};
+ data.networks = null; // Networks
+
+ /**
+ * ListId
+ * @param {type} fileToUpload
+ * @param {type} callback
+ * @returns {undefined}
+ */
+ var ListId = function (fileToUpload, callback) {
+ var result = $http.post('../server/index.php',
+ $.param({"token": Identity.getToken(), "task": "network", 'action': 'list_network_ids'}));
+
+ // Wait and handle the response
+ result.then(function (response) {
+ callback(parseUploadImageAnswer(response, false));
+ }, function (response) {
+ callback(parseUploadImageAnswer(response, true));
+ });
+ };
+
+
+ }]);
+
+
diff --git a/client/js/services/Test.js b/client/js/services/Test.js
new file mode 100644
index 0000000..f12c6b9
--- /dev/null
+++ b/client/js/services/Test.js
@@ -0,0 +1,8 @@
+var app = angular.module('mainApp',[]);
+app.controller('hassan', function($scope,$http){
+ $http.get('http://127.0.0.1/database.json').success(function(response){
+ $scope.persons = response.records;
+});
+
+
+});
diff --git a/client/partials/home/home.html b/client/partials/home/home.html
index aaf141d..1a6717d 100644..100755
--- a/client/partials/home/home.html
+++ b/client/partials/home/home.html
@@ -1,11 +1,11 @@
- <div class="panel panel-default">
+<div class="panel panel-default">
<div class="panel-heading">
Home
</div>
<div class="panel-body">
+
<div id="graphHolder"></div>
- Pour charger les machines, recharger la page (temporaire)<br />
- Selectionner une machine:
- <div ng-repeat="machine in machines"> <a ng-click="raiseShowMachineDetailsEvent(machine.id)"> {{ machine.name }}</a></div>
+ Selectionner une machine:
+ <div ng-repeat="machine in machines"> <a ng-click="raiseShowMachineDetailsEvent(machine.id)"> {{ machine.name }}</a></div>
</div>
</div>
diff --git a/client/partials/image/image.html b/client/partials/image/image.html
index 8af8af5..886a11d 100644
--- a/client/partials/image/image.html
+++ b/client/partials/image/image.html
@@ -1,10 +1,38 @@
- <div class="panel panel-default" ng-controller="imageCtrl">
+
+
+<div class="panel panel-default" ng-controller="imageCtrl">
<div class="panel-heading">
- Images disponibles
+ Image Manager
</div>
<div class="panel-body">
- <div ng-repeat="image in images">
- {{image.name}}
+
+
+ <div class="btn-group btn-group-md" role="group" aria-label="...">
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#uploadImageModal"">Upload</button>
+ <button type="button" class="btn btn-default">Download</button>
</div>
+ <p></p>
+ <table class="table table-hover">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Size</th>
+ <th>Action</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr ng-repeat="image in images">
+ <td>{{ image.name }}</td>
+ <td>{{ (image.size / 1048576).toFixed(2) }} MB</td>
+ <td><button type="button" class="btn btn-danger">Remove</button></td>
+ </tr>
+
+ </tbody>
+ </table>
+
+
+
+
+
</div>
</div>
diff --git a/client/partials/image/upload.html b/client/partials/image/upload.html
new file mode 100644
index 0000000..01c54b2
--- /dev/null
+++ b/client/partials/image/upload.html
@@ -0,0 +1,31 @@
+<div class="modal fade" id="uploadImageModal" ng-controller="uploadImageCtrl">
+ <div class="modal-dialog">
+ <div class="modal-content"></div>
+ </div>
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <!--<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>-->
+ <h4 class="modal-title">Upload Image</h4>
+
+ </div>
+
+ <div class="modal-body">
+
+ <form action="../server/index.php" method="post">
+ <input type="hidden" name="task" value="image" />
+ <input type="hidden" name="token" value="{{ token }}" />
+ <input type="hidden" name="action" value="uploadImage" />
+ <input type="hidden" name="id" value="2564" />
+ <input name="file" type="file" />
+ <input type="submit" value="Upload" />
+ </form>
+
+ <div class="modal-footer">
+ <!--<a href="#" data-dismiss="modal" class="btn btn-default">Close</a>-->
+
+ <a class="btn btn-lg btn-primary btn-block" id="loginButton" ng-click="doUpload()">Upload</a>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/client/vendors/angularjs/angular-file-upload.min.js b/client/vendors/angularjs/angular-file-upload.min.js
new file mode 100644
index 0000000..871ca34
--- /dev/null
+++ b/client/vendors/angularjs/angular-file-upload.min.js
@@ -0,0 +1,7 @@
+/*
+ angular-file-upload v2.2.0
+ https://github.com/nervgh/angular-file-upload
+*/
+
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["angular-file-upload"]=t():e["angular-file-upload"]=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=r(n(1)),o=r(n(2)),s=r(n(3)),a=r(n(4)),u=r(n(5)),l=r(n(6)),c=r(n(7)),f=r(n(8)),p=r(n(9)),d=r(n(10)),v=r(n(11)),h=r(n(12));angular.module(i.name,[]).value("fileUploaderOptions",o).factory("FileUploader",s).factory("FileLikeObject",a).factory("FileItem",u).factory("FileDirective",l).factory("FileSelect",c).factory("FileDrop",f).factory("FileOver",p).directive("nvFileSelect",d).directive("nvFileDrop",v).directive("nvFileOver",h).run(["FileUploader","FileLikeObject","FileItem","FileDirective","FileSelect","FileDrop","FileOver",function(e,t,n,r,i,o,s){e.FileLikeObject=t,e.FileItem=n,e.FileDirective=r,e.FileSelect=i,e.FileDrop=o,e.FileOver=s}])},function(e,t){e.exports={name:"angularFileUpload"}},function(e,t){"use strict";e.exports={url:"/",alias:"file",headers:{},queue:[],progress:0,autoUpload:!1,removeAfterUpload:!1,method:"POST",filters:[],formData:[],queueLimit:Number.MAX_VALUE,withCredentials:!1}},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},s=(r(n(1)),angular.copy),a=angular.extend,u=angular.forEach,l=angular.isObject,c=angular.isNumber,f=angular.isDefined,p=angular.isArray,d=angular.element;e.exports=function(e,t,n,r,v,h){var m=r.File,g=r.FormData,_=function(){function r(t){o(this,r);var n=s(e);a(this,n,t,{isUploading:!1,_nextIndex:0,_failFilterIndex:-1,_directives:{select:[],drop:[],over:[]}}),this.filters.unshift({name:"queueLimit",fn:this._queueLimitFilter}),this.filters.unshift({name:"folder",fn:this._folderFilter})}return i(r,{addToQueue:{value:function(e,t,n){var r=this,i=this.isArrayLikeObject(e)?e:[e],o=this._getFilters(n),s=this.queue.length,a=[];u(i,function(e){var n=new v(e);if(r._isValidFile(n,o,t)){var i=new h(r,e,t);a.push(i),r.queue.push(i),r._onAfterAddingFile(i)}else{var s=o[r._failFilterIndex];r._onWhenAddingFileFailed(n,s,t)}}),this.queue.length!==s&&(this._onAfterAddingAll(a),this.progress=this._getTotalProgress()),this._render(),this.autoUpload&&this.uploadAll()}},removeFromQueue:{value:function(e){var t=this.getIndexOfItem(e),n=this.queue[t];n.isUploading&&n.cancel(),this.queue.splice(t,1),n._destroy(),this.progress=this._getTotalProgress()}},clearQueue:{value:function(){for(;this.queue.length;)this.queue[0].remove();this.progress=0}},uploadItem:{value:function(e){var t=this.getIndexOfItem(e),n=this.queue[t],r=this.isHTML5?"_xhrTransport":"_iframeTransport";n._prepareToUploading(),this.isUploading||(this.isUploading=!0,this[r](n))}},cancelItem:{value:function(e){var t=this.getIndexOfItem(e),n=this.queue[t],r=this.isHTML5?"_xhr":"_form";n&&n.isUploading&&n[r].abort()}},uploadAll:{value:function(){var e=this.getNotUploadedItems().filter(function(e){return!e.isUploading});e.length&&(u(e,function(e){return e._prepareToUploading()}),e[0].upload())}},cancelAll:{value:function(){var e=this.getNotUploadedItems();u(e,function(e){return e.cancel()})}},isFile:{value:function(e){return this.constructor.isFile(e)}},isFileLikeObject:{value:function(e){return this.constructor.isFileLikeObject(e)}},isArrayLikeObject:{value:function(e){return this.constructor.isArrayLikeObject(e)}},getIndexOfItem:{value:function(e){return c(e)?e:this.queue.indexOf(e)}},getNotUploadedItems:{value:function(){return this.queue.filter(function(e){return!e.isUploaded})}},getReadyItems:{value:function(){return this.queue.filter(function(e){return e.isReady&&!e.isUploading}).sort(function(e,t){return e.index-t.index})}},destroy:{value:function(){var e=this;u(this._directives,function(t){u(e._directives[t],function(e){e.destroy()})})}},onAfterAddingAll:{value:function(e){}},onAfterAddingFile:{value:function(e){}},onWhenAddingFileFailed:{value:function(e,t,n){}},onBeforeUploadItem:{value:function(e){}},onProgressItem:{value:function(e,t){}},onProgressAll:{value:function(e){}},onSuccessItem:{value:function(e,t,n,r){}},onErrorItem:{value:function(e,t,n,r){}},onCancelItem:{value:function(e,t,n,r){}},onCompleteItem:{value:function(e,t,n,r){}},onCompleteAll:{value:function(){}},_getTotalProgress:{value:function(e){if(this.removeAfterUpload)return e||0;var t=this.getNotUploadedItems().length,n=t?this.queue.length-t:this.queue.length,r=100/this.queue.length,i=(e||0)*r/100;return Math.round(n*r+i)}},_getFilters:{value:function(e){if(!e)return this.filters;if(p(e))return e;var t=e.match(/[^\s,]+/g);return this.filters.filter(function(e){return-1!==t.indexOf(e.name)})}},_render:{value:function(){t.$$phase||t.$apply()}},_folderFilter:{value:function(e){return!(!e.size&&!e.type)}},_queueLimitFilter:{value:function(){return this.queue.length<this.queueLimit}},_isValidFile:{value:function(e,t,n){var r=this;return this._failFilterIndex=-1,t.length?t.every(function(t){return r._failFilterIndex++,t.fn.call(r,e,n)}):!0}},_isSuccessCode:{value:function(e){return e>=200&&300>e||304===e}},_transformResponse:{value:function(e,t){var r=this._headersGetter(t);return u(n.defaults.transformResponse,function(t){e=t(e,r)}),e}},_parseHeaders:{value:function(e){var t,n,r,i={};return e?(u(e.split("\n"),function(e){r=e.indexOf(":"),t=e.slice(0,r).trim().toLowerCase(),n=e.slice(r+1).trim(),t&&(i[t]=i[t]?i[t]+", "+n:n)}),i):i}},_headersGetter:{value:function(e){return function(t){return t?e[t.toLowerCase()]||null:e}}},_xhrTransport:{value:function(e){var t=this,n=e._xhr=new XMLHttpRequest,r=new g;if(this._onBeforeUploadItem(e),u(e.formData,function(e){u(e,function(e,t){r.append(t,e)})}),"number"!=typeof e._file.size)throw new TypeError("The file specified is no longer valid");r.append(e.alias,e._file,e.file.name),n.upload.onprogress=function(n){var r=Math.round(n.lengthComputable?100*n.loaded/n.total:0);t._onProgressItem(e,r)},n.onload=function(){var r=t._parseHeaders(n.getAllResponseHeaders()),i=t._transformResponse(n.response,r),o=t._isSuccessCode(n.status)?"Success":"Error",s="_on"+o+"Item";t[s](e,i,n.status,r),t._onCompleteItem(e,i,n.status,r)},n.onerror=function(){var r=t._parseHeaders(n.getAllResponseHeaders()),i=t._transformResponse(n.response,r);t._onErrorItem(e,i,n.status,r),t._onCompleteItem(e,i,n.status,r)},n.onabort=function(){var r=t._parseHeaders(n.getAllResponseHeaders()),i=t._transformResponse(n.response,r);t._onCancelItem(e,i,n.status,r),t._onCompleteItem(e,i,n.status,r)},n.open(e.method,e.url,!0),n.withCredentials=e.withCredentials,u(e.headers,function(e,t){n.setRequestHeader(t,e)}),n.send(r),this._render()}},_iframeTransport:{value:function(e){var t=this,n=d('<form style="display: none;" />'),r=d('<iframe name="iframeTransport'+Date.now()+'">'),i=e._input;e._form&&e._form.replaceWith(i),e._form=n,this._onBeforeUploadItem(e),i.prop("name",e.alias),u(e.formData,function(e){u(e,function(e,t){var r=d('<input type="hidden" name="'+t+'" />');r.val(e),n.append(r)})}),n.prop({action:e.url,method:"POST",target:r.prop("name"),enctype:"multipart/form-data",encoding:"multipart/form-data"}),r.bind("load",function(){var n="",i=200;try{n=r[0].contentDocument.body.innerHTML}catch(o){i=500}var s={response:n,status:i,dummy:!0},a={},u=t._transformResponse(s.response,a);t._onSuccessItem(e,u,s.status,a),t._onCompleteItem(e,u,s.status,a)}),n.abort=function(){var o,s={status:0,dummy:!0},a={};r.unbind("load").prop("src","javascript:false;"),n.replaceWith(i),t._onCancelItem(e,o,s.status,a),t._onCompleteItem(e,o,s.status,a)},i.after(n),n.append(i).append(r),n[0].submit(),this._render()}},_onWhenAddingFileFailed:{value:function(e,t,n){this.onWhenAddingFileFailed(e,t,n)}},_onAfterAddingFile:{value:function(e){this.onAfterAddingFile(e)}},_onAfterAddingAll:{value:function(e){this.onAfterAddingAll(e)}},_onBeforeUploadItem:{value:function(e){e._onBeforeUpload(),this.onBeforeUploadItem(e)}},_onProgressItem:{value:function(e,t){var n=this._getTotalProgress(t);this.progress=n,e._onProgress(t),this.onProgressItem(e,t),this.onProgressAll(n),this._render()}},_onSuccessItem:{value:function(e,t,n,r){e._onSuccess(t,n,r),this.onSuccessItem(e,t,n,r)}},_onErrorItem:{value:function(e,t,n,r){e._onError(t,n,r),this.onErrorItem(e,t,n,r)}},_onCancelItem:{value:function(e,t,n,r){e._onCancel(t,n,r),this.onCancelItem(e,t,n,r)}},_onCompleteItem:{value:function(e,t,n,r){e._onComplete(t,n,r),this.onCompleteItem(e,t,n,r);var i=this.getReadyItems()[0];return this.isUploading=!1,f(i)?void i.upload():(this.onCompleteAll(),this.progress=this._getTotalProgress(),void this._render())}}},{isFile:{value:function(e){return m&&e instanceof m}},isFileLikeObject:{value:function(e){return e instanceof v}},isArrayLikeObject:{value:function(e){return l(e)&&"length"in e}},inherit:{value:function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.super_=t}}}),r}();return _.prototype.isHTML5=!(!m||!g),_.isHTML5=_.prototype.isHTML5,_},e.exports.$inject=["fileUploaderOptions","$rootScope","$http","$window","FileLikeObject","FileItem"]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},s=(r(n(1)),angular.copy),a=angular.isElement,u=angular.isString;e.exports=function(){var e=function(){function e(t){o(this,e);var n=a(t),r=n?t.value:t,i=u(r)?"FakePath":"Object",s="_createFrom"+i;this[s](r)}return i(e,{_createFromFakePath:{value:function(e){this.lastModifiedDate=null,this.size=null,this.type="like/"+e.slice(e.lastIndexOf(".")+1).toLowerCase(),this.name=e.slice(e.lastIndexOf("/")+e.lastIndexOf("\\")+2)}},_createFromObject:{value:function(e){this.lastModifiedDate=s(e.lastModifiedDate),this.size=e.size,this.type=e.type,this.name=e.name}}}),e}();return e},e.exports.$inject=[]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},s=(r(n(1)),angular.copy),a=angular.extend,u=angular.element,l=angular.isElement;e.exports=function(e,t){var n=function(){function n(e,r,i){o(this,n);var c=l(r),f=c?u(r):null,p=c?null:r;a(this,{url:e.url,alias:e.alias,headers:s(e.headers),formData:s(e.formData),removeAfterUpload:e.removeAfterUpload,withCredentials:e.withCredentials,method:e.method},i,{uploader:e,file:new t(r),isReady:!1,isUploading:!1,isUploaded:!1,isSuccess:!1,isCancel:!1,isError:!1,progress:0,index:null,_file:p,_input:f}),f&&this._replaceNode(f)}return i(n,{upload:{value:function(){try{this.uploader.uploadItem(this)}catch(e){this.uploader._onCompleteItem(this,"",0,[]),this.uploader._onErrorItem(this,"",0,[])}}},cancel:{value:function(){this.uploader.cancelItem(this)}},remove:{value:function(){this.uploader.removeFromQueue(this)}},onBeforeUpload:{value:function(){}},onProgress:{value:function(e){}},onSuccess:{value:function(e,t,n){}},onError:{value:function(e,t,n){}},onCancel:{value:function(e,t,n){}},onComplete:{value:function(e,t,n){}},_onBeforeUpload:{value:function(){this.isReady=!0,this.isUploading=!0,this.isUploaded=!1,this.isSuccess=!1,this.isCancel=!1,this.isError=!1,this.progress=0,this.onBeforeUpload()}},_onProgress:{value:function(e){this.progress=e,this.onProgress(e)}},_onSuccess:{value:function(e,t,n){this.isReady=!1,this.isUploading=!1,this.isUploaded=!0,this.isSuccess=!0,this.isCancel=!1,this.isError=!1,this.progress=100,this.index=null,this.onSuccess(e,t,n)}},_onError:{value:function(e,t,n){this.isReady=!1,this.isUploading=!1,this.isUploaded=!0,this.isSuccess=!1,this.isCancel=!1,this.isError=!0,this.progress=0,this.index=null,this.onError(e,t,n)}},_onCancel:{value:function(e,t,n){this.isReady=!1,this.isUploading=!1,this.isUploaded=!1,this.isSuccess=!1,this.isCancel=!0,this.isError=!1,this.progress=0,this.index=null,this.onCancel(e,t,n)}},_onComplete:{value:function(e,t,n){this.onComplete(e,t,n),this.removeAfterUpload&&this.remove()}},_destroy:{value:function(){this._input&&this._input.remove(),this._form&&this._form.remove(),delete this._form,delete this._input}},_prepareToUploading:{value:function(){this.index=this.index||++this.uploader._nextIndex,this.isReady=!0}},_replaceNode:{value:function(t){var n=e(t.clone())(t.scope());n.prop("value",null),t.css("display","none"),t.after(n)}}}),n}();return n},e.exports.$inject=["$compile","FileLikeObject"]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},s=(r(n(1)),angular.extend);e.exports=function(){var e=function(){function e(t){o(this,e),s(this,t),this.uploader._directives[this.prop].push(this),this._saveLinks(),this.bind()}return i(e,{bind:{value:function(){for(var e in this.events){var t=this.events[e];this.element.bind(e,this[t])}}},unbind:{value:function(){for(var e in this.events)this.element.unbind(e,this.events[e])}},destroy:{value:function(){var e=this.uploader._directives[this.prop].indexOf(this);this.uploader._directives[this.prop].splice(e,1),this.unbind()}},_saveLinks:{value:function(){for(var e in this.events){var t=this.events[e];this[t]=this[t].bind(this)}}}}),e}();return e.prototype.events={},e},e.exports.$inject=[]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function l(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t);if(void 0===r){var i=Object.getPrototypeOf(e);return null===i?void 0:l(i,t,n)}if("value"in r&&r.writable)return r.value;var o=r.get;return void 0===o?void 0:o.call(n)},s=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(e.__proto__=t)},a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},u=(r(n(1)),angular.extend);e.exports=function(e){var t=function(e){function t(e){a(this,t);var n=u(e,{events:{$destroy:"destroy",change:"onChange"},prop:"select"});o(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,n),this.uploader.isHTML5||this.element.removeAttr("multiple"),this.element.prop("value",null)}return s(t,e),i(t,{getOptions:{value:function(){}},getFilters:{value:function(){}},isEmptyAfterSelection:{value:function(){return!!this.element.attr("multiple")}},onChange:{value:function(){var e=this.uploader.isHTML5?this.element[0].files:this.element[0],t=this.getOptions(),n=this.getFilters();this.uploader.isHTML5||this.destroy(),this.uploader.addToQueue(e,t,n),this.isEmptyAfterSelection()&&(this.element.prop("value",null),this.element.replaceWith(this.element=this.element.clone(!0)))}}}),t}(e);return t},e.exports.$inject=["FileDirective"]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function c(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t);if(void 0===r){var i=Object.getPrototypeOf(e);return null===i?void 0:c(i,t,n)}if("value"in r&&r.writable)return r.value;var o=r.get;return void 0===o?void 0:o.call(n)},s=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(e.__proto__=t)},a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},u=(r(n(1)),angular.extend),l=angular.forEach;e.exports=function(e){var t=function(e){function t(e){a(this,t);var n=u(e,{events:{$destroy:"destroy",drop:"onDrop",dragover:"onDragOver",dragleave:"onDragLeave"},prop:"drop"});o(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,n)}return s(t,e),i(t,{getOptions:{value:function(){}},getFilters:{value:function(){}},onDrop:{value:function(e){var t=this._getTransfer(e);if(t){var n=this.getOptions(),r=this.getFilters();this._preventAndStop(e),l(this.uploader._directives.over,this._removeOverClass,this),this.uploader.addToQueue(t.files,n,r)}}},onDragOver:{value:function(e){var t=this._getTransfer(e);this._haveFiles(t.types)&&(t.dropEffect="copy",this._preventAndStop(e),l(this.uploader._directives.over,this._addOverClass,this))}},onDragLeave:{value:function(e){e.currentTarget!==this.element[0]&&(this._preventAndStop(e),l(this.uploader._directives.over,this._removeOverClass,this))}},_getTransfer:{value:function(e){return e.dataTransfer?e.dataTransfer:e.originalEvent.dataTransfer}},_preventAndStop:{value:function(e){e.preventDefault(),e.stopPropagation()}},_haveFiles:{value:function(e){return e?e.indexOf?-1!==e.indexOf("Files"):e.contains?e.contains("Files"):!1:!1}},_addOverClass:{value:function(e){e.addOverClass()}},_removeOverClass:{value:function(e){e.removeOverClass()}}}),t}(e);return t},e.exports.$inject=["FileDirective"]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e},i=function(){function e(e,t){for(var n in t){var r=t[n];r.configurable=!0,r.value&&(r.writable=!0)}Object.defineProperties(e,t)}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=function l(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t);if(void 0===r){var i=Object.getPrototypeOf(e);return null===i?void 0:l(i,t,n)}if("value"in r&&r.writable)return r.value;var o=r.get;return void 0===o?void 0:o.call(n)},s=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(e.__proto__=t)},a=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},u=(r(n(1)),angular.extend);e.exports=function(e){var t=function(e){function t(e){a(this,t);var n=u(e,{events:{$destroy:"destroy"},prop:"over",overClass:"nv-file-over"});o(Object.getPrototypeOf(t.prototype),"constructor",this).call(this,n)}return s(t,e),i(t,{addOverClass:{value:function(){this.element.addClass(this.getOverClass())}},removeOverClass:{value:function(){this.element.removeClass(this.getOverClass())}},getOverClass:{value:function(){return this.overClass}}}),t}(e);return t},e.exports.$inject=["FileDirective"]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e};r(n(1));e.exports=function(e,t,n){return{link:function(r,i,o){var s=r.$eval(o.uploader);if(!(s instanceof t))throw new TypeError('"Uploader" must be an instance of FileUploader');var a=new n({uploader:s,element:i});a.getOptions=e(o.options).bind(a,r),a.getFilters=function(){return o.filters}}}},e.exports.$inject=["$parse","FileUploader","FileSelect"]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e};r(n(1));e.exports=function(e,t,n){return{link:function(r,i,o){var s=r.$eval(o.uploader);if(!(s instanceof t))throw new TypeError('"Uploader" must be an instance of FileUploader');if(s.isHTML5){var a=new n({uploader:s,element:i});a.getOptions=e(o.options).bind(a,r),a.getFilters=function(){return o.filters}}}}},e.exports.$inject=["$parse","FileUploader","FileDrop"]},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e["default"]:e};r(n(1));e.exports=function(e,t){return{link:function(n,r,i){var o=n.$eval(i.uploader);if(!(o instanceof e))throw new TypeError('"Uploader" must be an instance of FileUploader');var s=new t({uploader:o,element:r});s.getOverClass=function(){return i.overClass||s.overClass}}}},e.exports.$inject=["FileUploader","FileOver"]}])});
+//# sourceMappingURL=angular-file-upload.min.js.map \ No newline at end of file
diff --git a/client/vendors/angularjs/angular-upload.min.js b/client/vendors/angularjs/angular-upload.min.js
new file mode 100644
index 0000000..d75b94b
--- /dev/null
+++ b/client/vendors/angularjs/angular-upload.min.js
@@ -0,0 +1 @@
+"use strict";angular.module("lr.upload",["lr.upload.formdata","lr.upload.iframe","lr.upload.directives"]),angular.module("lr.upload.directives",[]),angular.module("lr.upload.directives").directive("uploadButton",["upload",function(a){return{restrict:"EA",scope:{data:"=?data",url:"@",id:"@",param:"@",method:"@",onUpload:"&",onSuccess:"&",onError:"&",onComplete:"&"},link:function(b,c,d){var e=angular.element(c),f=angular.element('<input id="'+b.id+'" type="file" />');if(e.append(f),f.on("change",function(){var c=angular.element(this);if(!c[0].files||0!==c[0].files.length){var e={url:b.url,method:b.method||"POST",forceIFrameUpload:b.$eval(d.forceIframeUpload)||!1,data:b.data||{}};e.data[b.param||"file"]=c,b.$apply(function(){b.onUpload({files:c[0].files})}),a(e).then(function(a){b.onSuccess({response:a}),b.onComplete({response:a})},function(a){b.onError({response:a}),b.onComplete({response:a})})}}),"required"in d&&d.$observe("required",function(a){var d=""===a?!0:b.$eval(a);f.attr("required",d),c.toggleClass("ng-valid",!d),c.toggleClass("ng-invalid ng-invalid-required",d)}),"accept"in d&&d.$observe("accept",function(a){f.attr("accept",a)}),a.support.formData){var g=function(){f.attr("multiple",!(!b.$eval(d.multiple)||b.$eval(d.forceIframeUpload)))};d.$observe("multiple",g),d.$observe("forceIframeUpload",g)}}}}]),angular.module("lr.upload.formdata",[]).factory("formDataTransform",function(){return function(a){var b=new FormData;return angular.forEach(a,function(a,c){if(angular.isElement(a)){var d=[];angular.forEach(a,function(a){angular.forEach(a.files,function(a){d.push(a)}),a.value=""}),0!==d.length&&(d.length>1?angular.forEach(d,function(a,d){b.append(c+"["+d+"]",a)}):b.append(c,d[0]))}else b.append(c,a)}),b}}).factory("formDataUpload",["$http","formDataTransform",function(a,b){return function(c){return c.transformRequest=b,c.method=c.method||"POST",c.headers=angular.extend(c.headers||{},{"Content-Type":void 0}),a(c)}}]),angular.module("lr.upload.iframe",[]).factory("iFrameUpload",["$q","$http","$document","$rootScope",function(a,b,c,d){function e(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0;c<a.length;c++)if(b===a[c])return c;return-1}function f(f){var g=[],h=a.defer(),i=h.promise;angular.forEach(f.data||{},function(a,b){angular.isElement(a)&&(delete f.data[b],a.attr("name",b),g.push(a))});var j=/\?/.test(f.url)?"&":"?";"DELETE"===f.method?(f.url=f.url+j+"_method=DELETE",f.method="POST"):"PUT"===f.method?(f.url=f.url+j+"_method=PUT",f.method="POST"):"PATCH"===f.method&&(f.url=f.url+j+"_method=PATCH",f.method="POST");var k=angular.element(c[0].body),l=d.$new(),m="iframe-transport-"+l.$id;l.$destroy();var n=angular.element("<form></form>");n.attr("target",m),n.attr("action",f.url),n.attr("method",f.method||"POST"),n.css("display","none"),g.length&&(n.attr("enctype","multipart/form-data"),n.attr("encoding","multipart/form-data"));var o=angular.element('<iframe name="'+m+'" src="javascript:false;"></iframe>');return o.on("load",function(){function a(a,b){var c=[];return angular.isFunction(b)?b(a,c):(angular.forEach(b,function(b){a=b(a,c)}),a)}function c(){var a=e(b.pendingRequests,f);-1!==a&&(b.pendingRequests.splice(a,1),f.$iframeTransportForm.remove(),delete f.$iframeTransportForm)}o.off("load").on("load",function(){var c;try{var d=this.contentWindow?this.contentWindow.document:this.contentDocument;if(c=angular.element(d.body).text(),!c.length)throw new Error}catch(e){}n.append(angular.element('<iframe src="javascript:false;"></iframe>'));try{c=a(c,b.defaults.transformResponse)}catch(e){}h.resolve({data:c,status:200,headers:[],config:f})}),angular.forEach(f.data,function(a,b){var c=angular.element('<input type="hidden" />');c.attr("name",b),c.val(a),n.append(c)}),angular.forEach(g,function(a){var b=a.clone(!0);a.after(b),n.append(a)}),f.$iframeTransportForm=n,b.pendingRequests.push(f),n[0].submit(),i.then(c,c)}),n.append(o),k.append(n),i}return f}]),angular.module("lr.upload").factory("upload",["$window","formDataUpload","iFrameUpload",function(a,b,c){function d(a){return e.formData&&!a.forceIFrameUpload?b(a):c(a)}var e={fileInput:!(new RegExp("(Android (1\\.[0156]|2\\.[01]))|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)|(w(eb)?OSBrowser)|(webOS)|(Kindle/(1\\.0|2\\.[05]|3\\.0))").test(a.navigator.userAgent)||angular.element('<input type="file">').prop("disabled")),fileUpload:!(!a.XMLHttpRequestUpload||!a.FileReader),formData:!!a.FormData};return d.support=e,d}]); \ No newline at end of file
diff --git a/client/vendors/jquery/dmuploader.min.js b/client/vendors/jquery/dmuploader.min.js
new file mode 100644
index 0000000..3c3231c
--- /dev/null
+++ b/client/vendors/jquery/dmuploader.min.js
@@ -0,0 +1,9 @@
+/*
+ * dmuploader.min.js - Jquery File Uploader - 0.1
+ * http://www.daniel.com.uy/projects/jquery-file-uploader/
+ *
+ * Copyright (c) 2013 Daniel Morales
+ * Dual licensed under the MIT and GPL licenses.
+ * http://www.daniel.com.uy/doc/license/
+ */
+(function(t){var n="dmUploader";var r={url:document.URL,method:"POST",extraData:{},maxFileSize:0,allowedTypes:"*",extFilter:null,dataType:null,fileName:"file",onInit:function(){},onFallbackMode:function(){message},onNewFile:function(e,t){},onBeforeUpload:function(e){},onComplete:function(){},onUploadProgress:function(e,t){},onUploadSuccess:function(e,t){},onUploadError:function(e,t){},onFileTypeError:function(e){},onFileSizeError:function(e){},onFileExtError:function(e){}};var i=function(e,n){this.element=t(e);this.settings=t.extend({},r,n);if(!this.checkBrowser()){return false}this.init();return true};i.prototype.checkBrowser=function(){if(window.FormData===undefined){this.settings.onFallbackMode.call(this.element,"Browser doesn't support Form API");return false}if(this.element.find("input[type=file]").length>0){return true}if(!this.checkEvent("drop",this.element)||!this.checkEvent("dragstart",this.element)){this.settings.onFallbackMode.call(this.element,"Browser doesn't support Ajax Drag and Drop");return false}return true};i.prototype.checkEvent=function(e,t){var t=t||document.createElement("div");var e="on"+e;var n=e in t;if(!n){if(!t.setAttribute){t=document.createElement("div")}if(t.setAttribute&&t.removeAttribute){t.setAttribute(e,"");n=typeof t[e]=="function";if(typeof t[e]!="undefined"){t[e]=undefined}t.removeAttribute(e)}}t=null;return n};i.prototype.init=function(){var e=this;e.queue=new Array;e.queuePos=-1;e.queueRunning=false;e.element.on("drop",function(t){t.preventDefault();var n=t.originalEvent.dataTransfer.files;e.queueFiles(n)});e.element.find("input[type=file]").on("change",function(n){var r=n.target.files;e.queueFiles(r);t(this).val("")});this.settings.onInit.call(this.element)};i.prototype.queueFiles=function(e){var n=this.queue.length;for(var r=0;r<e.length;r++){var i=e[r];if(this.settings.maxFileSize>0&&i.size>this.settings.maxFileSize){this.settings.onFileSizeError.call(this.element,i);continue}if(this.settings.allowedTypes!="*"&&!i.type.match(this.settings.allowedTypes)){this.settings.onFileTypeError.call(this.element,i);continue}if(this.settings.extFilter!=null){var s=this.settings.extFilter.toLowerCase().split(";");var o=i.name.toLowerCase().split(".").pop();if(t.inArray(o,s)<0){this.settings.onFileExtError.call(this.element,i);continue}}this.queue.push(i);var u=this.queue.length-1;this.settings.onNewFile.call(this.element,u,i)}if(this.queueRunning){return false}if(this.queue.length==n){return false}this.processQueue();return true};i.prototype.processQueue=function(){var n=this;n.queuePos++;if(n.queuePos>=n.queue.length){n.settings.onComplete.call(n.element);n.queuePos=n.queue.length-1;n.queueRunning=false;return}var r=n.queue[n.queuePos];var i=new FormData;i.append(n.settings.fileName,r);n.settings.onBeforeUpload.call(n.element,n.queuePos);t.each(n.settings.extraData,function(e,t){i.append(e,t)});n.queueRunning=true;t.ajax({url:n.settings.url,type:n.settings.method,dataType:n.settings.dataType,data:i,cache:false,contentType:false,processData:false,forceSync:false,xhr:function(){var r=t.ajaxSettings.xhr();if(r.upload){r.upload.addEventListener("progress",function(t){var r=0;var i=t.loaded||t.position;var s=t.total||e.totalSize;if(t.lengthComputable){r=Math.ceil(i/s*100)}n.settings.onUploadProgress.call(n.element,n.queuePos,r)},false)}return r},success:function(e,t,r){n.settings.onUploadSuccess.call(n.element,n.queuePos,e)},error:function(e,t,r){n.settings.onUploadError.call(n.element,n.queuePos,r)},complete:function(e,t){n.processQueue()}})};t.fn.dmUploader=function(e){return this.each(function(){if(!t.data(this,n)){t.data(this,n,new i(this,e))}})};t(document).on("dragenter",function(e){e.stopPropagation();e.preventDefault()});t(document).on("dragover",function(e){e.stopPropagation();e.preventDefault()});t(document).on("drop",function(e){e.stopPropagation();e.preventDefault()})})(jQuery)