edit.html (9134B)
1 <!DOCTYPE html> 2 <html lang="fr"> 3 <head> 4 <meta charset="utf-8" /> 5 <meta name="viewport" content="width=device-width"> 6 <title>Planification JDR</title> 7 <link rel="stylesheet" type="text/css" href="style.css" /> 8 <script> 9 var val_class=["val0","val1","val2","val3","val4","val5"]; 10 var val_text=["?","−−","−","0","+","++"]; 11 var all_data=null; 12 var radio_map=new Map(); 13 var spinner_map=new Map(); 14 var subject=null; 15 var sent=null; 16 var outbox=new Map(); 17 var sender=null; 18 var base_timeout=2000; 19 var retry_timeout=base_timeout; 20 21 window.onerror = function(msg, url, line) { 22 var item = document.createElement("li"); 23 item.appendChild(document.createTextNode(url + "@" + line + ": " + msg)); 24 document.getElementById("error-log").appendChild(item); 25 document.getElementById("error-div").style = "display:block"; 26 item.scrollIntoView(); 27 } 28 29 function pathname_to_topic(str) { 30 var components = str.split("/"); 31 var fileName = components[components.length - 1]; 32 var lastDotIndex = fileName.lastIndexOf("-"); 33 return lastDotIndex !== -1 ? fileName.substring(0, lastDotIndex) : ""; 34 } 35 36 var topic=pathname_to_topic(window.location.pathname); 37 38 async function send(){ 39 var req_body = (topic ? "topic=" + encodeURIComponent(topic) + "&" : "") + "sub=" + encodeURIComponent(subject); 40 for (const [key, value] of outbox) { 41 req_body += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(value); 42 } 43 sent = outbox; 44 outbox = new Map(); 45 const response = await fetch("do/set-pref", { 46 method: "POST", 47 cache: "no-store", 48 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 49 body: req_body, 50 }); 51 var to = base_timeout; 52 if (response.ok) { 53 for (const [key, value] of sent) { 54 if (!outbox.has(key)) { 55 spinner_map.get(key).style = "display:none"; 56 } 57 } 58 retry_timeout = base_timeout; 59 } else { 60 for (const [key, value] of sent) { 61 if (!outbox.has(key)) { 62 outbox.set(key, value); 63 } 64 } 65 to = retry_timeout; 66 retry_timeout *= 2; 67 } 68 sent = null; 69 if (outbox.size) { 70 sender = setTimeout(send, to); 71 } 72 } 73 74 function radio_click(name, value){ 75 spinner_map.get(name).style = "display:inline"; 76 outbox.set(name, value); 77 if (!sent) { 78 if (sender) { 79 clearTimeout(sender); 80 } 81 sender = setTimeout(send, 2000); 82 } 83 } 84 85 function new_table_line(name) { 86 var line = document.createElement("tr"); 87 88 var cell = document.createElement("td"); 89 cell.className = "date"; 90 cell.appendChild(document.createTextNode(name)); 91 line.appendChild(cell); 92 93 var radios = new Array; 94 95 for (const i in val_text) { 96 cell = document.createElement("td"); 97 var elt1 = document.createElement("label"); 98 var elt2 = document.createElement("input"); 99 elt2.type = "radio"; 100 elt2.name = name; 101 elt2.value = i; 102 elt2.onchange = function() { radio_click(name, i) }; 103 radios[i] = elt2; 104 elt1.appendChild(elt2); 105 elt1.appendChild(document.createTextNode(val_text[i])); 106 elt1.className = val_class[i]; 107 cell.appendChild(elt1); 108 if (i > 0) { 109 line.appendChild(cell); 110 } else { 111 line.insertBefore(cell, line.childNodes[0]); 112 } 113 } 114 radio_map.set(name, radios); 115 116 cell = document.createElement("td"); 117 elt1 = document.createElement("img"); 118 elt1.className = "spinner"; 119 elt1.src = "spinner.svg"; 120 elt1.style = "display:none"; 121 spinner_map.set(name, elt1); 122 cell.appendChild(elt1); 123 line.appendChild(cell); 124 125 return line; 126 } 127 128 function activate_subject(){ 129 document.getElementById("cur-subject").textContent = subject; 130 131 if (!subject) { 132 document.getElementById("change-form").style = "display:block"; 133 document.getElementById("cur-subject-p").style = "display:none"; 134 document.getElementById("pref-form").style = "display:none"; 135 document.getElementById("new-subject").style = "display:none"; 136 return false; 137 } else if (subject in all_data[1]) { 138 for (const [name, radios] of radio_map) { 139 for (const i in val_text) { 140 radios[i].checked = (i == (all_data[1][subject][name] || 0)); 141 } 142 } 143 144 document.getElementById("change-form").style = "display:none"; 145 document.getElementById("cur-subject-p").style = "display:block"; 146 document.getElementById("pref-form").style = "display:block"; 147 document.getElementById("new-subject").style = "display:none"; 148 return false; 149 } else { 150 document.getElementById("change-form").style = "display:none"; 151 document.getElementById("cur-subject-p").style = "display:block"; 152 document.getElementById("pref-form").style = "display:none"; 153 document.getElementById("new-subject").style = "display:block"; 154 return true; 155 } 156 } 157 158 async function reload_data(){ 159 document.getElementById("back-link").href = (topic ? topic + "-" : "") + "view.html"; 160 document.getElementById("reload-spinner").style = "display:inline"; 161 const response = await fetch((topic || "all") + ".json", { cache: "no-cache" }); 162 all_data = await response.json(); 163 164 var holder = document.getElementById("pref-table-body"); 165 while (holder.childNodes.length > 0) { 166 holder.removeChild(holder.childNodes[0]); 167 } 168 169 var line = null; 170 var cell = null; 171 var elt1 = null; 172 var elt2 = null; 173 174 radio_map.clear(); 175 spinner_map.clear(); 176 177 for (const name of all_data[0]) { 178 holder.appendChild(new_table_line(name)); 179 } 180 181 subject = localStorage.getItem("subject" + (topic ? "-" + topic : "")); 182 activate_subject(); 183 184 document.getElementById("reload-spinner").style = "display:none"; 185 } 186 187 async function create_subject(){ 188 document.getElementById("create-spinner").style = "display:inline"; 189 const response = await fetch("do/new-subject", { 190 method: "POST", 191 cache: "no-store", 192 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 193 body: (topic ? "topic=" + encodeURIComponent(topic) + "&" : "") + "name=" + encodeURIComponent(subject), 194 }); 195 document.getElementById("create-spinner").style = "display:none"; 196 197 if (response.ok) { 198 document.getElementById("new-subject").style = "display:none"; 199 reload_data(); 200 } 201 } 202 203 function set_subject(){ 204 subject = document.getElementById("set-subject").value; 205 localStorage.setItem("subject" + (topic ? "-" + topic : ""), subject); 206 activate_subject(); 207 return false; 208 } 209 210 function reset_subject(){ 211 document.getElementById("change-form").style = "display:block"; 212 document.getElementById("cur-subject-p").style = "display:none"; 213 } 214 </script> 215 </head> 216 <body onload="reload_data()"> 217 <h1>Planification JDR</h1> 218 <p> 219 <a href="view.html" id="back-link">Retour à la vue d'ensemble</a> 220 <input name="test" value="Recharger" type="button" onclick="reload_data()"> 221 <img id="reload-spinner" class="spinner" src="spinner.svg" style="display: none"> 222 </p> 223 <table style="margin: 1em"> 224 <tr><td colspan="2" style="text-align: left"><strong>Symboles des préférences :</strong></td></tr> 225 <tr> 226 <td class="val5">++</td> 227 <td style="text-align: left">j'ai très envie de jouer ce soir-là, je vais m'ennuyer autrement</td> 228 </tr> 229 <tr> 230 <td class="val4">+</td> 231 <td style="text-align: left">j'aimerais bien jouer ce soir-là</td> 232 </tr> 233 <tr> 234 <td class="val3">0</td> 235 <td style="text-align: left">je veux bien jouer mais ça ne me dérange pas de ne pas jouer</td> 236 </tr> 237 <tr> 238 <td class="val2">−</td> 239 <td style="text-align: left">je peux jouer ce soir-là mais ça ne m'arrange pas vraiment</td> 240 </tr> 241 <tr> 242 <td class="val1">−−</td> 243 <td style="text-align: left">je ne suis pas du tout disponible ce soir-là</td> 244 </tr> 245 <tr> 246 <td class="val0">?</td> 247 <td style="text-align: left">je ne veux pas me prononcer</td> 248 </tr> 249 </table> 250 <form id="change-form" onsubmit="return set_subject()"> 251 <p> 252 <label> 253 Pseudo : <input name="subject" id="set-subject" value="" type="text"> 254 </label> 255 <input name="submit" value="Valider" type="submit"> 256 </p> 257 </form> 258 <p id="cur-subject-p" style="display:none"> 259 Préférences pour <strong id=cur-subject></strong> 260 <input name="change-subject" value="Changer" type="button" onclick="reset_subject()"> 261 </p> 262 <form id="pref-form" style="display:block"> 263 <table> 264 <thead> 265 <tr id="table-header"> 266 <th></th> 267 <th>Date</th> 268 <th colspan="5">Préférence</th> 269 <th></th> 270 </tr> 271 </thead> 272 <tbody id="pref-table-body"> 273 <tr> 274 <td colspan="8"> 275 <img src="spinner.svg" with="5em" height"5em"> 276 </td> 277 </tr> 278 </tbody> 279 </table> 280 </form> 281 <p id="new-subject" style="display:none"> 282 <input name="submit" type="button" value="Créer" onclick="create_subject()"> 283 <img id="create-spinner" class="spinner" src="spinner.svg" style="display: none"> 284 </p> 285 <div id="error-div" style="display:none"> 286 <p>Error log:</p> 287 <ul id="error-log"><ul> 288 </div> 289 </body> 290 </html>