Commit 14f89f89d2048e84e4d879507422414200d8229a
1 parent
41e2fa5d
Nouvelle manière de configurer le réseau
Une nouvelle route "nodesconf" permet de configurer le réseau de noeuds d'une plus simple manière sans avoir à écrire un fichier YAML. Toute la partie front est opérationnelle, il ne reste qu'à traiter le JSON coté serveur pour mettre à jour la configuration.
Showing
5 changed files
with
282 additions
and
2 deletions
Show diff stats
PFE06/src/main/java/com/PFE/ServerManager/MainController.java
@@ -310,4 +310,15 @@ public class MainController { | @@ -310,4 +310,15 @@ public class MainController { | ||
310 | } | 310 | } |
311 | yaml.dump(data, writer); | 311 | yaml.dump(data, writer); |
312 | } | 312 | } |
313 | + | ||
314 | + @GetMapping(value="/nodesconf") | ||
315 | + public ModelAndView nodesconf() { | ||
316 | + ModelAndView modelAndView = new ModelAndView(); | ||
317 | + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); | ||
318 | + Customer customer = customerRepository.findByEmail(auth.getName()); | ||
319 | + modelAndView.addObject("customerName", customer.getEmail().split("@")[0]); | ||
320 | + modelAndView.addObject("customerRole", customer.getRole()); | ||
321 | + modelAndView.setViewName("nodesconf"); | ||
322 | + return modelAndView; | ||
323 | + } | ||
313 | } | 324 | } |
314 | \ No newline at end of file | 325 | \ No newline at end of file |
@@ -0,0 +1,137 @@ | @@ -0,0 +1,137 @@ | ||
1 | +var nodes = []; | ||
2 | +var sensors = []; | ||
3 | +var index = -1; | ||
4 | + | ||
5 | +var nodeName = document.getElementById("nodeName"); | ||
6 | +var nodeIP = document.getElementById("nodeIP"); | ||
7 | +var nodeArch = document.getElementById("nodeArch"); | ||
8 | +var sensorName = document.getElementById("sensorName"); | ||
9 | +var addSensor = document.getElementById("addSensor"); | ||
10 | +var prevNode = document.getElementById("prevNode"); | ||
11 | +var allDone = document.getElementById("allDone"); | ||
12 | +var nextNode = document.getElementById("nextNode"); | ||
13 | +var addNode = document.getElementById("addNode"); | ||
14 | +var delNode = document.getElementById("delNode"); | ||
15 | +var editNode = document.getElementById("editNode"); | ||
16 | + | ||
17 | +function deleteRow(r) { | ||
18 | + var i = r.parentNode.parentNode.rowIndex; | ||
19 | + var name = r.parentNode.parentNode.firstElementChild.innerText; | ||
20 | + | ||
21 | + function search(array) { | ||
22 | + return array.name === name; | ||
23 | + } | ||
24 | + | ||
25 | + var idx = sensors.findIndex(search); | ||
26 | + if (idx > -1) { | ||
27 | + sensors.splice(idx, 1); | ||
28 | + } | ||
29 | + | ||
30 | + document.getElementById("sensorsTable").deleteRow(i); | ||
31 | +} | ||
32 | + | ||
33 | +addSensor.addEventListener('click', function() { | ||
34 | + if(sensorName.value !== "") { | ||
35 | + var table = document.getElementById("sensorsTable"); | ||
36 | + var row = table.insertRow(0); | ||
37 | + var cell1 = row.insertCell(0); | ||
38 | + var cell2 = row.insertCell(1); | ||
39 | + cell1.innerHTML = sensorName.value; | ||
40 | + cell2.innerHTML = "<button type=\"button\" class=\"close\" aria-label=\"Close\" onclick=\"deleteRow(this)\">\n" + | ||
41 | + "<span aria-hidden=\"true\">×</span>\n" + | ||
42 | + "</button>"; | ||
43 | + sensors.push({"name": sensorName.value }); | ||
44 | + sensorName.value = ""; | ||
45 | + } | ||
46 | +}) | ||
47 | + | ||
48 | +function displayNode(index) { | ||
49 | + clearAll(); | ||
50 | + nodeName.value = nodes[index].name; | ||
51 | + nodeIP.value = nodes[index].ip; | ||
52 | + nodeArch.value = nodes[index].arch; | ||
53 | + sensors = nodes[index].sensors.slice(0); | ||
54 | + var table = document.getElementById("sensorsTable"); | ||
55 | + for(var i = 0; i < sensors.length; i++) { | ||
56 | + var row = table.insertRow(0); | ||
57 | + var cell1 = row.insertCell(0); | ||
58 | + var cell2 = row.insertCell(1); | ||
59 | + cell1.innerHTML = sensors[i].name; | ||
60 | + cell2.innerHTML = "<button type=\"button\" class=\"close\" aria-label=\"Close\" onclick=\"deleteRow(this)\">\n" + | ||
61 | + "<span aria-hidden=\"true\">×</span>\n" + | ||
62 | + "</button>"; | ||
63 | + } | ||
64 | +} | ||
65 | + | ||
66 | +function clearAll() { | ||
67 | + nodeName.value = ""; | ||
68 | + nodeIP.value = ""; | ||
69 | + nodeArch.value = ""; | ||
70 | + sensorName.value = ""; | ||
71 | + sensors.splice(0, sensors.length); | ||
72 | + document.getElementById("sensorsTable").innerHTML = ""; | ||
73 | +} | ||
74 | + | ||
75 | +allDone.addEventListener('click', function() { | ||
76 | + if(nodes.length !== 0) { | ||
77 | + console.log(JSON.stringify(nodes)); | ||
78 | + } | ||
79 | +}) | ||
80 | + | ||
81 | +prevNode.addEventListener('click', function() { | ||
82 | + index--; | ||
83 | + if(index < 0) { | ||
84 | + index = nodes.length - 1; | ||
85 | + } | ||
86 | + if(nodes.length != 0) { | ||
87 | + displayNode(index); | ||
88 | + } | ||
89 | +}) | ||
90 | + | ||
91 | +nextNode.addEventListener('click', function() { | ||
92 | + index++; | ||
93 | + if(index >= nodes.length) { | ||
94 | + index = 0; | ||
95 | + } | ||
96 | + if(nodes.length != 0) { | ||
97 | + displayNode(index); | ||
98 | + } | ||
99 | +}) | ||
100 | + | ||
101 | +addNode.addEventListener('click', function() { | ||
102 | + var node = { | ||
103 | + 'name': nodeName.value, | ||
104 | + 'ip': nodeIP.value, | ||
105 | + 'arch': nodeArch.value, | ||
106 | + 'sensors': sensors.slice(0) | ||
107 | + }; | ||
108 | + if(node.name === "" || node.ip === "" || node.arch === "" || sensors.length === 0) { | ||
109 | + $("#warningConf").modal(); | ||
110 | + } | ||
111 | + else { | ||
112 | + nodes.push(node); | ||
113 | + clearAll(); | ||
114 | + index = nodes.length; | ||
115 | + } | ||
116 | +}) | ||
117 | + | ||
118 | +editNode.addEventListener('click', function() { | ||
119 | + if(index !== -1 && index !== nodes.length) { | ||
120 | + nodes[index].name = nodeName.value; | ||
121 | + nodes[index].ip = nodeIP.value; | ||
122 | + nodes[index].arch = nodeArch.value; | ||
123 | + nodes[index].sensors = sensors.slice(0); | ||
124 | + clearAll(); | ||
125 | + index = nodes.length; | ||
126 | + } | ||
127 | +}) | ||
128 | + | ||
129 | +delNode.addEventListener('click', function() { | ||
130 | + if(index != nodes.length) { | ||
131 | + nodes.splice(index, 1); | ||
132 | + clearAll(); | ||
133 | + index = nodes.length; | ||
134 | + } | ||
135 | +}) | ||
136 | + | ||
137 | + |
PFE06/src/main/resources/templates/login.html
@@ -31,11 +31,11 @@ | @@ -31,11 +31,11 @@ | ||
31 | <div class="form-team"> | 31 | <div class="form-team"> |
32 | <input type="email" class="form-control" id="inputEmail" placeholder="Email" name="email"> | 32 | <input type="email" class="form-control" id="inputEmail" placeholder="Email" name="email"> |
33 | </div> | 33 | </div> |
34 | - | 34 | + <br/> |
35 | <div class="form-team"> | 35 | <div class="form-team"> |
36 | <input type="password" class="form-control" id="inputPassword" placeholder="Mot de passe" name="password"> | 36 | <input type="password" class="form-control" id="inputPassword" placeholder="Mot de passe" name="password"> |
37 | </div> | 37 | </div> |
38 | - | 38 | + <br/> |
39 | <button @click.prevent="login" type="submit" class="btn btn-primary">Se connecter</button> | 39 | <button @click.prevent="login" type="submit" class="btn btn-primary">Se connecter</button> |
40 | 40 | ||
41 | </form> | 41 | </form> |
@@ -0,0 +1,129 @@ | @@ -0,0 +1,129 @@ | ||
1 | +<!DOCTYPE html> | ||
2 | +<html xmlns:th="http://www.thymeleaf.org"> | ||
3 | +<head> | ||
4 | + <meta charset="utf-8"> | ||
5 | + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||
6 | + <link rel="stylesheet" th:href="@{/css/all.css}"> | ||
7 | + <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> | ||
8 | + <title>Configuration des noeuds</title> | ||
9 | +</head> | ||
10 | +<body> | ||
11 | +<!-- NAV BAR --> | ||
12 | +<nav class="navbar navbar-expand-lg navbar-dark bg-dark"> | ||
13 | + <div class="container"> | ||
14 | + <a th:href="@{/home}"><span class="navbar-brand"><img style="max-width:32px;" src="/pfelogo.png"></span></a> | ||
15 | + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation"> | ||
16 | + <span class="navbar-toggler-icon"></span> | ||
17 | + </button> | ||
18 | + <div class="collapse navbar-collapse" id="navbarNavAltMarkup"> | ||
19 | + <div class="navbar-nav mr-auto"> | ||
20 | + <a class="nav-item nav-link" th:href="@{/upload}">Uploader un fichier</a> | ||
21 | + <div th:remove="tag" th:switch="${customerRole}"> | ||
22 | + <div th:remove="tag" th:case="'ADMIN'"> | ||
23 | + <a class="nav-item nav-link" th:href="@{/registration}">Enregistrer des utilisateurs</a> | ||
24 | + <a class="nav-item nav-link" th:href="@{/all}">Liste des utilisateurs</a> | ||
25 | + <a class="nav-item nav-link" th:href="@{/update}">Paramétrer une mise à jour</a> | ||
26 | + </div> | ||
27 | + <div th:remove="tag" th:case="'USER'"> | ||
28 | + <a class="nav-item nav-link" th:href="@{/update}">Paramétrer une mise à jour</a> | ||
29 | + </div> | ||
30 | + </div> | ||
31 | + </div> | ||
32 | + </div> | ||
33 | + <div class="collapse navbar-collapse ml-3" id="navbarNavAltMarkup2" > | ||
34 | + <div class="navbar-nav ml-auto"> | ||
35 | + <a class="nav-item nav-link btn btn-danger active" th:href="@{/logout}">Déconnexion</a> | ||
36 | + </div> | ||
37 | + </div> | ||
38 | + </div> | ||
39 | +</nav> | ||
40 | + | ||
41 | + | ||
42 | +<!-- TABLE PART --> | ||
43 | +<div class="container"> | ||
44 | + <h1 style="margin-bottom:50px; margin-top:50px; border-bottom:1px solid #CCC; padding-bottom:20px;">Configuration des noeuds</h1> | ||
45 | + | ||
46 | + <div class="input-group mb-3"> | ||
47 | + <div class="input-group-prepend"> | ||
48 | + <span class="input-group-text">Nom</span> | ||
49 | + </div> | ||
50 | + <input id="nodeName" type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default"> | ||
51 | + </div> | ||
52 | + | ||
53 | + <div class="input-group mb-3"> | ||
54 | + <div class="input-group-prepend"> | ||
55 | + <span class="input-group-text">IP</span> | ||
56 | + </div> | ||
57 | + <input id="nodeIP" type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default"> | ||
58 | + </div> | ||
59 | + | ||
60 | + <div class="input-group mb-3"> | ||
61 | + <div class="input-group-prepend"> | ||
62 | + <span class="input-group-text">Architecture</span> | ||
63 | + </div> | ||
64 | + <input id="nodeArch" type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default"> | ||
65 | + </div> | ||
66 | + | ||
67 | + <h3>Capteurs</h3><br/> | ||
68 | + | ||
69 | + <div class="input-group mb-3"> | ||
70 | + <div class="input-group-prepend"> | ||
71 | + <span class="input-group-text">Nom</span> | ||
72 | + </div> | ||
73 | + <input id="sensorName" type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default"> | ||
74 | + </div> | ||
75 | + | ||
76 | + <button id="addSensor" type="button" class="btn btn-primary" style="margin-bottom:50px;">Ajouter un capteur</button> | ||
77 | + | ||
78 | + <table id="sensorsTable" class="table" style="margin-bottom:50px;"> | ||
79 | + </table> | ||
80 | + | ||
81 | + <button id="addNode" type="button" class="btn btn-success" style="margin-bottom:50px;">Ajouter ce noeud</button> | ||
82 | + <button id="editNode" type="button" class="btn btn-warning" style="margin-bottom:50px;">Modifier ce noeud</button> | ||
83 | + <button id="delNode" type="button" class="btn btn-danger" style="margin-bottom:50px;">Supprimer ce noeud</button> | ||
84 | + | ||
85 | + <div class="container"> | ||
86 | + <div class="row"> | ||
87 | + <div class="col-sm" style="text-align:left;"> | ||
88 | + <button id="prevNode" type="button" class="btn btn-secondary"><</button> | ||
89 | + </div> | ||
90 | + <div class="col-sm" style="text-align:center;"> | ||
91 | + <button id="allDone" type="button" class="btn btn-primary btn-lg btn-block">Terminer</button> | ||
92 | + </div> | ||
93 | + <div class="col-sm" style="text-align:right"> | ||
94 | + <button id="nextNode" type="button" class="btn btn-secondary">></button> | ||
95 | + </div> | ||
96 | + </div> | ||
97 | + </div> | ||
98 | + | ||
99 | + | ||
100 | +</div> | ||
101 | + | ||
102 | + | ||
103 | +<div class="modal fade" id="warningConf" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> | ||
104 | + <div class="modal-dialog modal-dialog-centered" role="document"> | ||
105 | + <div class="modal-content"> | ||
106 | + <div class="modal-header"> | ||
107 | + <h5 class="modal-title" id="modal-title">Attention</h5> | ||
108 | + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||
109 | + <span aria-hidden="true">×</span> | ||
110 | + </button> | ||
111 | + </div> | ||
112 | + <div id="modal-content" class="modal-body"> | ||
113 | + Certains champs sont vides ! | ||
114 | + </div> | ||
115 | + <div class="modal-footer"> | ||
116 | + <button id="modal-button" type="button" class="btn btn-secondary" data-dismiss="modal">Fermer</button> | ||
117 | + </div> | ||
118 | + </div> | ||
119 | + </div> | ||
120 | +</div> | ||
121 | + | ||
122 | + | ||
123 | +<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> | ||
124 | +<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> | ||
125 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> | ||
126 | +<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script> | ||
127 | +<script th:src="@{/js/nodes.js}"></script> | ||
128 | +</body> | ||
129 | +</html> |
PFE06/src/main/resources/templates/registration.html
@@ -61,9 +61,11 @@ | @@ -61,9 +61,11 @@ | ||
61 | <div class="form-team"> | 61 | <div class="form-team"> |
62 | <input type="email" class="form-control" id="username" placeholder="Entrer l'email" name="email"> | 62 | <input type="email" class="form-control" id="username" placeholder="Entrer l'email" name="email"> |
63 | </div> | 63 | </div> |
64 | + <br/> | ||
64 | <div class="form-team"> | 65 | <div class="form-team"> |
65 | <input type="password" class="form-control" id="password" placeholder="Entrer le mot de passe" name="password"> | 66 | <input type="password" class="form-control" id="password" placeholder="Entrer le mot de passe" name="password"> |
66 | </div> | 67 | </div> |
68 | + <br/> | ||
67 | <div class="form3"> | 69 | <div class="form3"> |
68 | <input type="radio" id="role1" name="role" value="ADMIN"> | 70 | <input type="radio" id="role1" name="role" value="ADMIN"> |
69 | <label for="role1">Admin</label> | 71 | <label for="role1">Admin</label> |
@@ -71,6 +73,7 @@ | @@ -71,6 +73,7 @@ | ||
71 | <input type="radio" id="role2" name="role" value="USER" checked="checked"> <!--//"checked" empeche l'utilisateur de ne rien séléctionner--> | 73 | <input type="radio" id="role2" name="role" value="USER" checked="checked"> <!--//"checked" empeche l'utilisateur de ne rien séléctionner--> |
72 | <label for="role2">User</label> | 74 | <label for="role2">User</label> |
73 | </div> | 75 | </div> |
76 | + <br/> | ||
74 | <button @click.prevent="registration" type="submit" class="btn btn-primary">Ajouter</button> | 77 | <button @click.prevent="registration" type="submit" class="btn btn-primary">Ajouter</button> |
75 | </form> | 78 | </form> |
76 | </div> | 79 | </div> |