function fetch_game_groups(gameid, cb) { let req = { action: "get_game_groups", gameid: gameid }; request(req).then(resp => { let groups = JSON.parse(resp); let groupsJoined = groups.join(", "); cb(groupsJoined); }); } function list_all_games() { let req = {action: "get_all_game_headers"}; let tbody = document.getElementById("game_manager_table"); tbody.innerHTML = ""; request(req).then(resp => { let games = JSON.parse(resp); for (let i = 0; i < games.length; i++) { let g = games[i]; let row = document.createElement("tr"); let chkbox = document.createElement("input"); chkbox.type = "checkbox"; chkbox.name = "game_chkbox"; chkbox.game = g; let tdChkBox = document.createElement("td"); tdChkBox.appendChild(chkbox); tdChkBox.classList.add("checkbox"); let tdGameName = create_table_cell(g["name"]); let tdGameDescription = create_table_cell(g["description"]); let tdOwner = create_table_cell(g["owner"]); row.append(tdChkBox, tdGameName, tdGameDescription, tdOwner); tbody.appendChild(row); let edit_group_action = () => { create_edit_game(g); }; tdGameName.addEventListener("click", edit_group_action); tdGameDescription.addEventListener("click", edit_group_action); tdOwner.addEventListener("click", edit_group_action); } }); } function get_full_hostname() { return window.location.origin + window.location.pathname; } var EDITED_GAME = null; function create_edit_game(game = null) { EDITED_GAME = game; let updating = game !== null; let nameF = document.getElementById("game_name"); let descriptionF = document.getElementById("game_description"); let submit_btn = document.getElementById("game_editor_submit_btn"); let ownerF = document.getElementById("game_owner"); let contributorsF = document.getElementById("game_contributors"); let gameFileF = document.getElementById("game_file"); let download_challenges_btn = document.getElementById("download_challenges_btn"); let show_game_file_upload_btn = document.getElementById("show_game_file_upload"); let cancel_game_file_upload_btn = document.getElementById("cancel_game_file_upload"); let edit_challenges_btn = document.getElementById("edit_challenges_btn"); let groupF = document.getElementById("game_groups"); let time_limitedChk = document.getElementById("time_limited"); let time_limitF = document.getElementById("time_limit"); let repeatableChk = document.getElementById("repeatable"); let publicChk = document.getElementById("public"); let publicUrlF = document.getElementById("public_url"); let hide_public_url_field = () => { publicUrlF.hidden = !publicChk.checked; } let hide_public_option = () => { let hide = (!repeatableChk.checked) || (time_limitedChk.checked); if (hide) { publicChk.checked = false; } publicChk.disabled = hide; hide_public_url_field(); } if (!updating) { // creating a new game nameF.value = ""; descriptionF.value = ""; submit_btn.value = "Létrehozás" ownerF.value = USERDATA["nickname"]; ownerF.readOnly = true; contributorsF.value = ""; groupF.value = ""; time_limitedChk.checked = false; repeatableChk.checked = true; publicChk.checked = false; publicUrlF.value = ""; // hide additional controls hide("additional_controls"); } else { // editing an existing one nameF.value = game["name"]; descriptionF.value = game["description"]; submit_btn.value = "Mentés" ownerF.value = game["owner"]; ownerF.readOnly = false; contributorsF.value = game["contributors"].join(", "); fetch_game_groups(game["_id"], (groups) => { groupF.value = groups; }); publicChk.addEventListener("change", hide_public_url_field); publicChk.checked = game["public"]; publicUrlF.hidden = !publicChk.checked; publicUrlF.value = game["public_id"]; let props = game["properties"]; let time_limit = Math.max(Number(props["time_limit"]), 0); time_limitF.value = seconds_to_time(time_limit); time_limitedChk.checked = time_limit > 0; time_limitedChk.addEventListener("change", hide_public_option); handle_time_limit_chkbox(); repeatableChk.checked = props["repeatable"]; repeatableChk.addEventListener("change", hide_public_option); hide_public_option(); // show additional controls show("additional_controls"); } gameFileF.value = ""; let game_file_present = updating && game["game_file_present"]; if (game_file_present) { show(download_challenges_btn); show(edit_challenges_btn); edit_challenges_btn.onclick = () => { edit_challenges(game); }; } else { hide(download_challenges_btn); hide(edit_challenges_btn); } show_hide_gamefile_upload(false); submit_btn.onclick = () => { let game_name = document.getElementById("game_name").value.trim(); if (updating && time_limitedChk.checked && time_limitF.validity.patternMismatch) { alert("Hibás időformátum!") return; } if (game_name !== "") { let reqData = { name: game_name, description: descriptionF.value.trim(), owner: updating ? ownerF.value.trim() : USERDATA["nickname"], contributors: contributorsF.value.trim(), groups: groupF.value.trim(), public: publicChk.checked, properties: { time_limit: updating ? (time_limitedChk.checked ? time_to_seconds(time_limitF.value) : 0) : 0, repeatable: updating ? repeatableChk.checked : false } }; if (updating) { reqData["_id"] = game["_id"]; } let req = { action: updating ? "update_game" : "create_game", data: JSON.stringify(reqData) }; let uploading_game_file = gameFileF.files.length > 0; if (uploading_game_file) { // append game file if selected req["game_file"] = gameFileF.files[0]; } request(req).then(resp => { if (uploading_game_file) { let file_upload_status = JSON.parse(resp); alert(`Importálás eredménye:\n${file_upload_status["n"]} kérdés, ${file_upload_status["encoding"]} szövegkódolással`); } list_all_games(); }); hide("game_editor_window"); } }; show("game_editor_window"); } function show_hide_gamefile_upload(en) { if (en) { // hide("download_challenges_btn"); hide("show_game_file_upload"); show("game_file"); show("cancel_game_file_upload"); } else { // show("download_challenges_btn"); show("show_game_file_upload"); hide("game_file"); hide("cancel_game_file_upload"); document.getElementById("game_file").value = ""; } } function download_challenges() { let action = "export_game_file_csv"; let gameid = EDITED_GAME["_id"]; window.open(`interface.php?action=${action}&gameid=${gameid}`, "_blank"); } function get_selected_games() { let selected_chkboxes = document.getElementsByName("game_chkbox"); let selected_games = []; selected_chkboxes.forEach((chkbox) => { if (chkbox.checked) { selected_games.push(chkbox.game); } }); return selected_games; } function delete_games() { let games = get_selected_games(); if (games.length === 0) { return; } let game_names = []; let game_ids = []; games.forEach((g) => { game_names.push(g["name"]); game_ids.push(g["_id"]); }); let msg = "Biztosan törölni kívánja a következő játéko(ka)t?\n\n" + game_names.join(", ") + "\n\n" + "A törlés nem vonható vissza!"; if (confirm(msg)) { let req = {action: "delete_games", ids: game_ids.join(",")}; request(req).then(resp => { list_all_games(); }); } } function handle_time_limit_chkbox() { let time_limitedChk = document.getElementById("time_limited"); let time_limitF = document.getElementById("time_limit"); time_limitF.disabled = !time_limitedChk.checked; } function edit_challenges(game) { let req = {action: "get_challenges", gameid: game["_id"]}; request(req).then(resp => { console.log(JSON.parse(resp)); }); } function list_results_by_game(game) { let req = {action: "get_results_by_gameid", gameid: game["_id"]}; request(req).then(resp => { let rd = document.getElementById("results_display"); let results = JSON.parse(resp); if (results.length === 0) { return; } rd.innerHTML = ""; let n = results.length; results.sort((a, b) => { return Number(b["_id"]) - Number(a["_id"]) }); // sort records by ID let results_by_nickname = {}; results.forEach((record) => { let nickname = record["nickname"]; if (!results_by_nickname.hasOwnProperty(nickname)) { results_by_nickname[nickname] = []; } results_by_nickname[nickname].push(record); }); let nicknames = Object.keys(results_by_nickname); // mark best of the results nicknames.forEach((nickname) => { let result_group = results_by_nickname[nickname]; let best_entry = null; let best_percentage = -1.0; result_group.forEach((result) => { result["best"] = false; if (result["state"] === "concluded") { let percentage = result["summary"]["correct_answer_n"] / result["summary"]["challenge_n"]; if ((best_entry === null) || (percentage >= best_percentage)) { best_percentage = percentage; best_entry = result; } } }); if (best_entry !== null) { best_entry["best"] = true; } }); // print the grouped results nicknames.forEach((nickname) => { let result_group = results_by_nickname[nickname]; let test_group_box = document.createElement("section"); test_group_box.classList.add("summary-group") let nickname_box = document.createElement("section"); nickname_box.classList.add("summary-nickname-box"); nickname_box.innerText = nickname; test_group_box.append(nickname_box); result_group.forEach((record) => { let concluded = record["state"] === "concluded"; let test_summary_record = document.createElement("section"); test_summary_record.classList.add("test-summary-record"); // let sequence_number_sec = document.createElement("section"); // sequence_number_sec.classList.add("summary-name-id-block"); // sequence_number_sec.innerText = record["nickname"] + "#" + n; let duration_sec = document.createElement("section"); duration_sec.classList.add("summary-duration"); let start_time = unix_time_to_human_readable(record["start_time"]); duration_sec.innerHTML = `${start_time}-` test_summary_record.append(duration_sec); if (concluded) { let end_time = unix_time_to_human_readable(record["end_time"]); let summary = record["summary"]; duration_sec.innerHTML += `
${end_time}
${summary["correct_answer_n"]}/${summary["challenge_n"]}`; let percentage = document.createElement("section"); percentage.classList.add("summary-percentage"); let r = Math.floor((summary["correct_answer_n"] / summary["challenge_n"]) * 100); percentage.innerHTML = `${r}%`; test_summary_record.append(percentage); if (record["best"]) { let best_badge = document.createElement("section"); best_badge.classList.add("summary-best-badge"); best_badge.innerText = "LEGJOBB"; test_summary_record.append(best_badge); } } test_summary_record.addEventListener("click", () => { window.open(`testground.php?testid=${record["_id"]}&view_only=true`, "_blank"); }); test_group_box.appendChild(test_summary_record); n--; }); rd.append(test_group_box); }); show("results_viewer_window"); }); } function generate_game_report_by_groups() { let gameid = EDITED_GAME["_id"]; let filter = document.getElementById("report_filter").value.trim() let groups = document.getElementById("report_groups").value.trim() let outtype = document.getElementById("report_output_type").value; let report_url = `interface.php?action=generate_report_by_groups&gameid=${gameid}&groups=${groups}&filter=${filter}&outtype=${outtype}`; report_url = report_url.replace("#", "%23"); window.open(report_url, "_blank"); } // function hint_all_groups(target_element_id) { // const hintbox_insert_fn = (record) => { // let targetF = document.getElementById(target_element_id); // let groups = explode_sanitize_string_list(targetF.value); // groups.pop(); // groups.push(record); // targetF.value = groups.join(", "); // close_hintbox(true); // } // // let req = { // action: "search_groups", // } // // open_hintbox_at(target_element_id, req, print_group_name, hintbox_insert_fn); // }