source: src/main/webapp/newtournament.xhtml@ 7

Last change on this file since 7 was 7, checked in by bart, 5 years ago

Release 1.1.0

File size: 11.9 KB
RevLine 
[1]1<?xml version="1.0" encoding="UTF-8"?>
2<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
3<head>
4<title>Profiles and Domains list</title>
5<link rel="stylesheet" type="text/css" href="style.css" />
6
7</head>
8<body onload="init()">
9 <h1>Tournament</h1>
10
11 On this page you can configure the settings for running a new
12 tournament and start the tournament.
13 <br />
14 <br />
15
16 <select>
17 <option value="APP">All Permutations Tournament Protocol
18 (APP)</option>
19 </select>
20 <br />
21 <br />
[6]22 <input type="number" id="partiespersession" name="tentacles" min="2"
23 max="10" value="2" /> Number of parties in each session
[1]24 <br />
25
[6]26 <input type="checkbox" id="reuseparties" /> Pick parties with return
27 when creating sessions
[1]28 <br />
29
30 <br />
31 <div id="box" class="box">
[6]32 Session Protocol settings <br /> Session Protocol: <select>
[1]33 <option value="SAOP">SAOP</option>
[6]34 </select> <br /> Deadline: <input type="number" id="deadlinevalue"
35 name="deadline" min="1" max="10000" value="10" /> <select
36 id="deadlinetype">
[1]37 <option value="TIME">seconds</option>
38 <option value="ROUNDS">rounds</option>
39 </select>
40 </div>
41 <br />
42
43 <div id="box" class="box">
[6]44 <br /> Domain/Profile Server: <input type="url" name="url"
[7]45 id="profilesserverurl" value="localhost:8080/profilesserver-1.1.0"
[1]46 pattern=".*:[0-9]+/profilesserver" size="30"
[6]47 onchange="connectDomain()"> </input> <br /> Domain: <select
48 id="domainselection" onchange="selectDomain()">
[1]49 <!-- <option>Waiting for profiles server</option> -->
[6]50 </select> <br /> <br />
[1]51 <button onclick="addProfile()">Add</button>
52 Profile: <select id="profileselection">
53 <!-- <option>Waiting for partiesserver</option> -->
[6]54 </select> <br /> <br />
[1]55
56 <table id="profiles">
57 <thead>
58 <th align="left">Selected Profiles</th>
59 </thead>
60 <tbody id="profilesList">
61 <tr>
62 </tr>
63
64 </tbody>
65 </table>
66 <br />
67 </div>
68 <br />
69 <div id="box" class="box">
[6]70 <br /> Parties Server: <input type="url" name="url"
[7]71 id="partiesserverurl" value="localhost:8080/partiesserver-1.1.0"
[1]72 pattern=".*:[0-9]+/partiesserver" size="30"
[6]73 onchange="connectParties()"> </input> <br /> <br />
[1]74 Party: <select id="partyselection">
75 <!-- <option>Waiting for partiesserver</option> -->
[6]76 </select> <br /> Parameters: { <input type="text" id="parameters"
77 onchange="updateParameters()" value="" maxlength="100" /> } <br />
78 <button onclick="addParty()">Add</button>
79
80 <br /> <br />
[1]81 <table>
82 <thead>
[6]83 <th align="left">Party</th>
84 <th align="left">Parameters</th>
[1]85 </thead>
86 <tbody id="partiesList">
87 <tr id="partiesList">
88 </tr>
89
90 </tbody>
91 </table>
92
93 </div>
94 <br />
95 <form>
[6]96 <input id="startbutton" type="button" value="Start Tournament"
97 onclick="start()" />
[1]98 </form>
[6]99 <div id="started" style="visibility: hidden">
100 Your tournament started. Click <a href="" id="logref">here</a> to view
101 the log file.
[1]102 </div>
103
104</body>
105
106<script type="application/javascript">
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
[6]125
[1]126 // FIXME quick and dirty code. No clean MVC
127
128
129 <![CDATA[
130 "use strict";
131
132 var domainwebsocket = null;
133 var partieswebsocket=null;
134 // currently known domains (and profiles) as coming from domainwebsocket.
135 // keys are domain names, values are list of profile names
136 var knowndomains={};
137
138 var parties=[];
139 var profiles=[]
[6]140 // current setting of parameters
141 var parameters = {};
[1]142
143
144 /**
145 Refresh known domains using given profilesserver URL.
146 Called when user enters URL for domain server.
147 */
148 function connectDomain() {
149 if (domainwebsocket!=null) {
150 domainwebsocket.close();
151 domainwebsocket=null;
152 }
153 var url=document.getElementById("profilesserverurl").value;
154 var target = "ws://"+url+"/websocket/liststream";
155 if ('WebSocket' in window) {
156 domainwebsocket = new WebSocket(target);
157 } else if ('MozWebSocket' in window) {
158 domainwebsocket = new MozWebSocket(target);
159 } else {
160 alert('WebSocket is not supported by this browser. Please use a newer browser');
161 return;
162 }
163 domainwebsocket.onopen = function () {
164 // whatever.
165 };
166 domainwebsocket.onmessage = function (event) {
167 updateDomainComboBox(JSON.parse(event.data));
168 };
169 domainwebsocket.onclose = function (event) {
170 alert('Info: Server closed connection. Code: ' + event.code +
171 (event.reason == "" ? "" : ", Reason: " + event.reason));
172 domainwebsocket=null;
173 updateDomainComboBox({});
174 };
175 }
176
177 /**
178 Sets a new knowndomains value and Updates the contents of the domain selector combobox.
179 @param the known domains, a map of the form {"jobs":["jobs1","jobs2"]}
180 where the keys are the names of the available domains nd the values a list of the available profiles in that domain.
181
182 */
183 function updateDomainComboBox(newdomains) {
184 knowndomains=newdomains
185 var combobox = document.getElementById("domainselection");
186 combobox.options.length=0;
187 for (var domain in knowndomains) {
188 var option = document.createElement('option');
189 option.text = option.value = domain;
190 combobox.add(option, 0);
191 }
192 selectDomain();
193 }
194 /**
195 Refresh known parties using given partiesserver URL.
196 Called when user enters URL for parties server.
197 */
198 function connectParties() {
199 if (partieswebsocket!=null) {
200 partieswebsocket.close();
201 partieswebsocket=null;
202 }
203 var url=document.getElementById("partiesserverurl").value;
204 var target = "ws://"+url+"/available";
205 if ('WebSocket' in window) {
206 partieswebsocket = new WebSocket(target);
207 } else if ('MozWebSocket' in window) {
208 partieswebsocket = new MozWebSocket(target);
209 } else {
210 alert('WebSocket is not supported by this browser. Please use a newer browser');
211 return;
212 }
213 partieswebsocket.onopen = function () {
214 // whatever.
215 };
216 partieswebsocket.onmessage = function (event) {
217 updateParties(JSON.parse(event.data));
218 };
219 partieswebsocket.onclose = function (event) {
220 alert('Info: Server closed connection. Code: ' + event.code +
221 (event.reason == "" ? "" : ", Reason: " + event.reason));
222 partieswebsocket=null;
223 updateParties({});
224 };
225 }
226
227
228 function updateParties(parties) {
229 var combobox = document.getElementById("partyselection");
230 combobox.options.length=0;
231 for (var party in parties) {
232 var option = document.createElement('option');
233 option.text = option.value = parties[party].uri;
234 combobox.add(option, 0);
235 }
236 }
237
238
239
[6]240 /**
241 updates parameters field to match the given text.
242 */
243 function updateParameters() {
244 var text="{"+document.getElementById("parameters").value+"}";
245 try {
246 parameters=JSON.parse(text);
247 } catch(e) {
248 alert("Parameters can not be parsed. "+e);
249 return;
250 }
251 }
[1]252
253 /**
254 Called when the selected domain changes. Assumes knowndomains has been set.
255 Updates the available profiles in the profile combobox.
256 @param selection the name of the selected domain.
257 */
258 function selectDomain() {
259 // determined current selection
260 var domaincombobox = document.getElementById("domainselection");
261 if (domaincombobox.options.length==0) return; // fixme clean profiles options?
262 var domain = domaincombobox.options[domaincombobox.selectedIndex].value;
263
264 var profilecombo = document.getElementById("profileselection");
265 profilecombo.options.length=0;
266 for (var profile in knowndomains[domain]) {
267 var option = document.createElement('option');
268 option.text = option.value = knowndomains[domain][profile];
269 profilecombo.add(option, 0);
270 }
271 }
272
273 /**
274 Called when user clicks "Add"
275 */
276 function addParty() {
277 var partycombo = document.getElementById("partyselection");
278
279 if (partycombo.options.length==0) {
280 alert("Please set partier server and select a party");
281 return;
282 }
[6]283 parties.push({"partyref":partycombo.options[partycombo.selectedIndex].value, "parameters":parameters})
[1]284 updatePartyTable();
285 }
286
287 /** updates the party table, to match the #partyprofiles list. */
288 function updatePartyTable() {
289 var table = document.getElementById("partiesList");
290 table.innerHTML = ""; // clear table
291 for ( var party in parties) {
292 var row = table.insertRow(-1);
293 var cell1 = row.insertCell(-1);
[6]294 var cell2 = row.insertCell(-1);
295 cell1.innerHTML = parties[party]["partyref"];
296 cell2.innerHTML = JSON.stringify(parties[party]["parameters"]);
[1]297 }
298
299 }
300
301 /**
302 Called when user clicks "Add" to add a profile
303 */
304 function addProfile() {
305 var profilecombo = document.getElementById("profileselection");
306
307 if (profilecombo.options.length==0) {
308 alert("Please set domain/profile server and select a domain and a profile");
309 return;
310 }
311 profiles.push(profilecombo.options[profilecombo.selectedIndex].value)
312 updateProfileTable(); // what, MVC?
313 }
314
315 /** updates the party table, to match the #partyprofiles list. */
316 function updateProfileTable() {
317 var table = document.getElementById("profilesList");
318 table.innerHTML = ""; // clear table
319 for ( var profile in profiles) {
320 var row = table.insertRow(-1);
321 var cell1 = row.insertCell(-1);
322 cell1.innerHTML = profiles[profile];
323 }
324
325 }
326
327 /**
328 start the tournament as currently set on this page.
329 We need to send a TournamentSettings object to the server, which typically looks like this
330 but is protocol dependent (currently we do SAOP)
331
332 {"AllPermutationsSettings":{"parties":["party1","party2"],
333 "profiles":["profile1","profile2","profile3"],
334 "reuseParties":false,
335 "partiesPerSession":2,
336 "sessionsettings":{"SAOPSettings":{"participants":[],"deadline":{"deadlinetime":{"durationms":10}}}}}}
337
338 participants are already in the global partyprofiles dictionary
339 */
340 function start() {
341 var npersession = document.getElementById("partiespersession").value;
342
343 if (parties.length < npersession || npersession <2) {
344 alert("At least "+npersession+" parties are needed.");
345 return;
346 }
347
348 if (profiles.length < npersession) {
349 alert("At least "+npersession+" profiles are needed.");
350 return;
351 }
352
353 // see https://www.w3schools.com/xml/dom_httprequest.asp
354 var xmlHttp = new XMLHttpRequest();
355 xmlHttp.onreadystatechange = function() {
356 if (this.readyState == 4) {
357 if (this.status == 200) {
358 document.getElementById("startbutton").disabled=true;
359 document.getElementById("started").setAttribute("style","");
360 document.getElementById("logref").href="log/"+this.responseText+".json";
361 } else
362 alert("request failed:"+this.statusText);
363 }
364 }
365 xmlHttp.open("POST", "run", true);
366 xmlHttp.send(makeRequest());
367 }
368
369 /**
370 @return a json request package containing a AllPermutationsSettings
371 */
372 function makeRequest() {
373 var deadline={};
374 var value = document.getElementById("deadlinevalue").value;
375 var dtypecombo = document.getElementById("deadlinetype");
376 if (dtypecombo.options[dtypecombo.selectedIndex].value=="TIME") {
377 deadline["deadlinetime"] = { "durationms": 1000*value};
378 } else {
379 // ROUNDS
380 deadline["deadlinerounds"] = {"rounds": value, "durationms": 10000};
381 }
382
[3]383 var reuseParties = document.getElementById("reuseparties").checked;
[1]384 var sessionSettings = {"SAOPSettings":{"participants":[],"deadline":deadline}};
385 return JSON.stringify({"AllPermutationsSettings":{"parties":parties,"profiles":profiles,"reuseParties":reuseParties,"partiesPerSession":2,"sessionsettings":sessionSettings}});
386 }
387
388 /**
389 Initialize the page after html is loaded.
390 */
391 function init() {
[7]392 document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.1.0"
393 document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.1.0"
[2]394
395
[1]396 connectDomain();
397 connectParties();
398 }
399
400
401 ]]>
402
403
404
405
[6]406
[1]407</script>
408
409</html>
Note: See TracBrowser for help on using the repository browser.