diff options
| author | Loic GUEGAN <loic@Manzerbredes.home> | 2016-05-04 18:50:28 +0200 |
|---|---|---|
| committer | Loic GUEGAN <loic@Manzerbredes.home> | 2016-05-04 18:50:28 +0200 |
| commit | f819bc0c909dd85c4d98c8fb870ce5c6fce37383 (patch) | |
| tree | ea08f0571975164755a81aa40d6933f71628f78f | |
| parent | f4f2f50f21292a002e0becf6fcea7a22b7514e32 (diff) | |
Add machine creation overlay
| -rwxr-xr-x | client/index.html | 6 | ||||
| -rwxr-xr-x | client/js/controllers/home/home.js | 463 | ||||
| -rw-r--r-- | client/js/controllers/home/machineCreation.js | 16 | ||||
| -rwxr-xr-x | client/partials/home/home.html | 6 | ||||
| -rw-r--r-- | client/partials/home/machineCreation.html | 70 | ||||
| -rw-r--r-- | client/partials/home/machineDetails.html | 80 |
6 files changed, 371 insertions, 270 deletions
diff --git a/client/index.html b/client/index.html index d04955c..483d4ea 100755 --- a/client/index.html +++ b/client/index.html @@ -24,6 +24,7 @@ <!-- Overlay --> <div ng-include="'./partials/login.html'"></div> <div ng-include="'./partials/home/machineDetails.html'"></div> + <div ng-include="'./partials/home/machineCreation.html'"></div> <div ng-include="'./partials/loading.html'"></div> <div ng-include="'./partials/image/upload.html'"></div> <div ng-include="'./partials/image/edit.html'"></div> @@ -92,7 +93,8 @@ <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/home/machineDetails.js"></script> + <script src="./js/controllers/home/machineCreation.js"></script> <script src="./js/controllers/network/network.js"></script> <script src="./js/controllers/image/image.js"></script> <script src="./js/controllers/image/upload.js"></script> @@ -100,7 +102,7 @@ <!-- Includes and dependencies for jointJS --> - + <script src="./vendors/jointjs/dependencies//lodash.min.js"></script> <script src="./vendors/jointjs/dependencies/backbone-min.js"></script> <script src="./vendors/jointjs/js/joint.min.js"></script> diff --git a/client/js/controllers/home/home.js b/client/js/controllers/home/home.js index 287e63a..7731500 100755 --- a/client/js/controllers/home/home.js +++ b/client/js/controllers/home/home.js @@ -3,231 +3,238 @@ * * @param {$scope} $scope The $scope service from angular */ -mainApp.controller('homeCtrl', [ '$scope', 'Compute', '$rootScope', 'Loading','Identity', 'Image', function ($scope, Compute, $rootScope, Loading, Identity, Image) -{ - // Function to call after pull all data about machines - var callMeAfterPullData=function(data){ - //$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 - } - } - }; - - // 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(){ - 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) - }); - - 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')); - }); - } - - // Function to call after pull all data about machines - var callMeAfterPullData=function(data){ - //$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 - } - } - }; - - // 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(); - - - - //Read the adjacencyList and build the elements and the links according to it - function buildGraphFromAdjacencyList(adjacencyList) { - - var elements = []; - var links = []; - - _.each(adjacencyList['vms'], function(vm) { - elements.push(makeElement(vm)); - }); - _.each(adjacencyList['links'], function(link) { - links.push(makeLink(link[0], link[1] , link[2], link[3])); - }); - // 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. - return elements.concat(links); - } - - //Return a new link linking the parent and child elements with the interfaces names given in parameters - function makeLink(parentElementLabel, childElementLabel, Iparent, Ichild) { - - return new joint.dia.Link({ - source: { id: parentElementLabel }, - target: { id: childElementLabel }, - labels: [ - { position: 20, attrs: { text: { text: Iparent } }}, - { position: -20, attrs: { text: { text: Ichild } }} - ] - }); - } - - //Return a new element - function makeElement(vm) { - var label = vm[0]; - - var maxLineLength = _.max(label.split('\n'), function(l) { return l.length; }).length; - - // Compute width/height of the rectangle based on the number - // of lines in the label and the letter size. 0.6 * letterSize is - // an approximation of the monospace font letter width. - var width = 130; - var height = 80; - 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 } - } - }); - } - } -}]); +mainApp.controller('homeCtrl', ['$scope', 'Compute', '$rootScope', 'Loading', 'Identity', 'Image', function ($scope, Compute, $rootScope, Loading, Identity, Image) + { + // Function to call after pull all data about machines + var callMeAfterPullData = function (data) { + //$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 + } + } + }; + + // On user login + $scope.$on('loginEvent', function () { + tryToRetrieveData(); + }); + + + $scope.raiseShowMachineCreationEvent = function (){ + $rootScope.$broadcast("showMachineCreationEvent"); + }; + + // 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 () { + 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) + }); + + 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')); + }); + } + + // Function to call after pull all data about machines + var callMeAfterPullData = function (data) { + //$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 + } + } + }; + + // 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(); + + + + //Read the adjacencyList and build the elements and the links according to it + function buildGraphFromAdjacencyList(adjacencyList) { + + var elements = []; + var links = []; + + _.each(adjacencyList['vms'], function (vm) { + elements.push(makeElement(vm)); + }); + _.each(adjacencyList['links'], function (link) { + links.push(makeLink(link[0], link[1], link[2], link[3])); + }); + // 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. + return elements.concat(links); + } + + //Return a new link linking the parent and child elements with the interfaces names given in parameters + function makeLink(parentElementLabel, childElementLabel, Iparent, Ichild) { + + return new joint.dia.Link({ + source: {id: parentElementLabel}, + target: {id: childElementLabel}, + labels: [ + {position: 20, attrs: {text: {text: Iparent}}}, + {position: -20, attrs: {text: {text: Ichild}}} + ] + }); + } + + //Return a new element + function makeElement(vm) { + var label = vm[0]; + + var maxLineLength = _.max(label.split('\n'), function (l) { + return l.length; + }).length; + + // Compute width/height of the rectangle based on the number + // of lines in the label and the letter size. 0.6 * letterSize is + // an approximation of the monospace font letter width. + var width = 130; + var height = 80; + 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} + } + }); + } + } + }]); diff --git a/client/js/controllers/home/machineCreation.js b/client/js/controllers/home/machineCreation.js new file mode 100644 index 0000000..11315dd --- /dev/null +++ b/client/js/controllers/home/machineCreation.js @@ -0,0 +1,16 @@ +/** + * The home controller + * + * @param {$scope} $scope The $scope service from angular + */ +mainApp.controller('machineCreationCtrl', ['$scope', 'Compute', '$rootScope', '$timeout', 'Identity', function ($scope, Compute, $rootScope, $timeout, Identity) + { + + + $scope.name = "loic" + // When we need to show details of machine + $scope.$on('showMachineCreationEvent', function (eventName) { + $('#machineCreationModal').modal({backdrop: false, keyboard: true}); + }); + + }]); diff --git a/client/partials/home/home.html b/client/partials/home/home.html index e724388..1a4b085 100755 --- a/client/partials/home/home.html +++ b/client/partials/home/home.html @@ -9,6 +9,12 @@ <div class="col-md-12"> <div id="graphHolder"></div> </div> + + </div> + <div class="row"> + <div class="col-md-12"> + <button type="button" class="btn btn-default" ng-click="raiseShowMachineCreationEvent()">Create machine</button> + </div> </div> </div> </div> diff --git a/client/partials/home/machineCreation.html b/client/partials/home/machineCreation.html new file mode 100644 index 0000000..ee2f952 --- /dev/null +++ b/client/partials/home/machineCreation.html @@ -0,0 +1,70 @@ +<div class="modal" id="machineCreationModal" ng-controller="machineCreationCtrl" > + <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">Create Machine</h4> + + </div> + <div class="modal-body"> + + <form class="form-horizontal" role="form"> + <div class="form-group"> + <label class="control-label col-sm-2" for="email">Name</label> + <div class="col-sm-10"> + <p class="form-control-static">{{ name}}</p> + </div> + </div> + <div class="form-group"> + <label class="control-label col-sm-2" for="pwd">State</label> + <div class="col-sm-10"> + <span ng-if="machine.status == 'ACTIVE'">Online</span> + <span ng-if="machine.status !== 'ACTIVE'">Offline</span> + + <button class="btn btn-danger" ng-if="machine.status == 'ACTIVE'" ng-click="toggleMachineState()">Turn Off</button> + <button class="btn btn-success" ng-if="machine.status !== 'ACTIVE'" ng-click="toggleMachineState()">Turn On</button> + <img src="images/spin/32x32/Preloader_1.gif" ng-if="machineIsStarting"></span> + + + </div> + </div> + <fieldset class="form-group"> + <label class="control-label col-sm-2">RAM</label> + <select class="col-sm-20" id="ramSelected"> + <option ng-repeat="ram in axioms.ram" ng-selected="machine.ram == ram">{{ ram}}</option> + </select> + <span>MB</span> + </fieldset> + + <fieldset class="form-group"> + <label class="control-label col-sm-2">Disk</label> + <select class="col-sm-20" id="ramSelected"> + <option ng-repeat="disk in axioms.disk" ng-selected="machine.disk == disk">{{ disk}}</option> + </select> + </fieldset> + + <fieldset class="form-group"> + <label class="control-label col-sm-2">Image</label> + <select class="col-sm-20" id="ramSelected"> + <option ng-repeat="image in axioms.images" ng-selected="machine.imageId == Object.keys(image)">{{ image.name}}</option> + </select> + </fieldset> + + + + + + </form> + + + </div> + <div class="modal-footer"> + <a href="#" data-dismiss="modal" class="btn btn-primary">Apply</a> + <a href="#" data-dismiss="modal" class="btn btn-default">Cancel</a> + </div> + </div> + </div> +</div> diff --git a/client/partials/home/machineDetails.html b/client/partials/home/machineDetails.html index c4c8a38..c34158d 100644 --- a/client/partials/home/machineDetails.html +++ b/client/partials/home/machineDetails.html @@ -11,56 +11,56 @@ </div> <div class="modal-body"> - <form class="form-horizontal" role="form"> - <div class="form-group"> - <label class="control-label col-sm-2" for="email">Name</label> - <div class="col-sm-10"> - <p class="form-control-static">{{ machine.name }}</p> - </div> - </div> - <div class="form-group"> - <label class="control-label col-sm-2" for="pwd">State</label> - <div class="col-sm-10"> - <span ng-if="machine.status=='ACTIVE'">Online</span> - <span ng-if="machine.status!=='ACTIVE'">Offline</span> - - <button class="btn btn-danger" ng-if="machine.status=='ACTIVE'" ng-click="toggleMachineState()">Turn Off</button> - <button class="btn btn-success" ng-if="machine.status!=='ACTIVE'" ng-click="toggleMachineState()">Turn On</button> - <img src="images/spin/32x32/Preloader_1.gif" ng-if="machineIsStarting"></span> + <form class="form-horizontal" role="form"> + <div class="form-group"> + <label class="control-label col-sm-2" for="email">Name</label> + <div class="col-sm-10"> + <p class="form-control-static">{{ machine.name}}</p> + </div> + </div> + <div class="form-group"> + <label class="control-label col-sm-2" for="pwd">State</label> + <div class="col-sm-10"> + <span ng-if="machine.status == 'ACTIVE'">Online</span> + <span ng-if="machine.status !== 'ACTIVE'">Offline</span> + + <button class="btn btn-danger" ng-if="machine.status == 'ACTIVE'" ng-click="toggleMachineState()">Turn Off</button> + <button class="btn btn-success" ng-if="machine.status !== 'ACTIVE'" ng-click="toggleMachineState()">Turn On</button> + <img src="images/spin/32x32/Preloader_1.gif" ng-if="machineIsStarting"></span> - - </div> - </div> - <fieldset class="form-group"> - <label class="control-label col-sm-2">RAM</label> - <select class="col-sm-20" id="ramSelected"> - <option ng-repeat="ram in axioms.ram" ng-selected="machine.ram == ram">{{ ram }}</option> - </select> - <span>MB</span> - </fieldset> - <fieldset class="form-group"> - <label class="control-label col-sm-2">Disk</label> - <select class="col-sm-20" id="ramSelected"> - <option ng-repeat="disk in axioms.disk" ng-selected="machine.disk == disk">{{ disk }}</option> - </select> - </fieldset> + </div> + </div> + <fieldset class="form-group"> + <label class="control-label col-sm-2">RAM</label> + <select class="col-sm-20" id="ramSelected"> + <option ng-repeat="ram in axioms.ram" ng-selected="machine.ram == ram">{{ ram}}</option> + </select> + <span>MB</span> + </fieldset> - <fieldset class="form-group"> - <label class="control-label col-sm-2">Image</label> - <select class="col-sm-20" id="ramSelected"> - <option ng-repeat="image in axioms.images" ng-selected="machine.imageId == Object.keys(image)">{{ image.name }}</option> - </select> - </fieldset> + <fieldset class="form-group"> + <label class="control-label col-sm-2">Disk</label> + <select class="col-sm-20" id="ramSelected"> + <option ng-repeat="disk in axioms.disk" ng-selected="machine.disk == disk">{{ disk}}</option> + </select> + </fieldset> + <fieldset class="form-group"> + <label class="control-label col-sm-2">Image</label> + <select class="col-sm-20" id="ramSelected"> + <option ng-repeat="image in axioms.images" ng-selected="machine.imageId == Object.keys(image)">{{ image.name}}</option> + </select> + </fieldset> - </form> + </form> - </div> + + </div> <div class="modal-footer"> <a href="#" data-dismiss="modal" class="btn btn-primary">Apply</a> <a href="#" data-dismiss="modal" class="btn btn-default">Cancel</a> |
