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

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

Initial Release

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