From eb53ce3a46f77c310380b24f531fd9f770331dfe Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 8 Feb 2023 14:59:12 +0100 Subject: [PATCH 01/10] Moved button to open MUMIE Task on top of grading list --- view.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/view.php b/view.php index 9890d44..718cd7e 100644 --- a/view.php +++ b/view.php @@ -77,21 +77,20 @@ $redirecturl = new moodle_url('/mod/mumie/view.php', array('id' => $id, 'action' => 'open')); echo $OUTPUT->header(); - echo $grader->view_grading_table(); $buttonattributes = array( - "class" => "btn btn-primary", - "href" => $redirecturl, - "style" => "margin:10px auto; display: table;" - ); + "class" => "btn btn-primary", + "href" => $redirecturl, + "style" => "margin:10px auto; display: table;" + ); if ($mumietask->launchcontainer == MUMIE_LAUNCH_CONTAINER_WINDOW) { $buttonattributes["target"] = "_blank"; } - echo html_writer::tag( "a", - "Open MUMIE Task", + get_string('mumie_open_task', 'mod_mumie'), $buttonattributes ); + echo $grader->view_grading_table(); echo $OUTPUT->footer(); } else if ($action == "open") { From 220834df6a8c75a20ad2d6b4036e48f07c9d5550 Mon Sep 17 00:00:00 2001 From: tobias Date: Wed, 8 Feb 2023 15:03:26 +0100 Subject: [PATCH 02/10] Updated changelog --- changelog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog.md b/changelog.md index f1a6ecb..166a7f1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,12 @@ # MumieTask - Changelog All important changes to this plugin will be documented in this file. + +## [v1.4.10] - TODO + +### Changed +- Button to open a MUMIE Task in grading view is moved on top of participant list + ## [v1.4.9] - 2023-01-11 ### Fixed From 4dbfcfb371148c81e0a09dccbdecfdc5fc891d92 Mon Sep 17 00:00:00 2001 From: tobias Date: Mon, 13 Feb 2023 15:57:41 +0100 Subject: [PATCH 03/10] Added button to directly open Multi problem selector from mod_form --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 13 +++++++++++++ changelog.md | 3 +++ lang/de/mumie.php | 4 +++- lang/en/mumie.php | 4 +++- mod_form.php | 7 +++++++ version.php | 4 ++-- 8 files changed, 33 insertions(+), 6 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index aed9d79..9e7bba6 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1,3 +1,3 @@ -define("mod_mumie/mod_form",["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],(function(){var lmsSelectorUrl,systemLanguage,serverStructure,serverDropDown,languageElem,propertySelectionInputs,selectedTaskProperties,selectedTaskProp,taskSelectionInputs,selectedTasks,selectedTaskIds,sectionInputs,addServerButton=document.getElementById("id_add_server_button"),missingConfig=document.getElementsByName("mumie_missing_config")[0],serverController=(serverDropDown=document.getElementById("id_server"),{init:function(structure){serverStructure=structure},getSelectedServer:function(){var selectedServerName=serverDropDown.options[serverDropDown.selectedIndex].text;return serverStructure.find((function(server){return server.name===selectedServerName}))},disable:function(){serverDropDown.disabled=!0,function(elem){for(;elem.firstChild;)elem.removeChild(elem.firstChild)}(serverDropDown)},getAllServers:function(){return serverStructure}}),problemSelectorController=function(){var problemSelectorWindow,problemSelectorButton=document.getElementById("id_prb_selector_btn"),mumieOrg=document.getElementsByName("mumie_org")[0].value;function sendResponse(response){problemSelectorWindow&&problemSelectorWindow.postMessage(JSON.stringify(response),lmsSelectorUrl)}function sendSuccess(){var message=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";sendResponse({success:!0,message:message})}function addMessageListener(){window.addEventListener("message",(function(event){if(event.origin===lmsSelectorUrl){var importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link+"?lang="+importObj.language),taskController.setIsGraded(isGraded),sendSuccess(),window.focus(),require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0],type:"info"})})).fail(notification.exception)}))}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}}),!1)}return{init:function(){var gradingType=taskController.getGradingType();problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true","_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener()},disable:function(){problemSelectorButton.disabled=!0}}}(),courseController=function(){var courseNameElem=document.getElementById("id_mumie_course"),coursefileElem=document.getElementsByName("mumie_coursefile")[0];function _updateCourseName(){var _selectedCourse$name$,selectedCourse=courseController.getSelectedCourse(),selectedLanguage=langController.getSelectedLanguage();selectedCourse&&selectedLanguage&&(courseNameElem.value=null===(_selectedCourse$name$=selectedCourse.name.find((function(translation){return translation.language===selectedLanguage})))||void 0===_selectedCourse$name$?void 0:_selectedCourse$name$.value)}return{init:function(){_updateCourseName()},getSelectedCourse:function(){return serverController.getSelectedServer().courses.find((function(course){return course.coursefile===coursefileElem.value}))},updateCourseName:function(){_updateCourseName()},setCourse:function(courseFile){var coursefile;coursefile=courseFile,coursefileElem.value=coursefile,_updateCourseName()}}}(),langController=(languageElem=document.getElementById("id_language"),{getSelectedLanguage:function(){return languageElem.value},setLanguage:function(lang){if(!function(lang){return courseController.getSelectedCourse().languages.includes(lang)}(lang))throw new Error("Selected language not available");languageElem.value=lang,courseController.updateCourseName()}}),taskController=function(){var taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element"),isGradedElem=document.getElementById("id_mumie_isgraded");function updateName(){var newHeadline=function(task){if(!task)return null;var selectedLanguage=langController.getSelectedLanguage(),headlineWrapper=task.headline.find((function(localHeadline){return localHeadline.language===selectedLanguage}));return headlineWrapper?headlineWrapper.name:null}(taskController.getSelectedTask());(function(){if(0===nameElem.value.length)return!1;return!serverController.getAllServers().flatMap((function(server){return server.courses})).flatMap((function(course){return course.tasks})).flatMap((function(task){return task.headline})).map((function(headline){return headline.name})).concat(courseController.getSelectedCourse().name.map((function(n){return n.value}))).includes(nameElem.value)})()||(nameElem.value=newHeadline),taskDisplayElement.value=newHeadline}function getLocalizedLinkFromTask(task){return task.link+"?lang="+langController.getSelectedLanguage()}return{init:function(){updateName()},getSelectedTask:function(){var selectedLink=taskSelectionInput.value,selectedCourse=courseController.getSelectedCourse();if(!selectedCourse)return null;var tasks=selectedCourse.tasks.slice();return tasks.push(function(course){var headline=[];for(var i in course.name){var name=course.name[i];headline.push({name:name.value,language:name.language})}return{link:course.link,headline:headline}}(selectedCourse)),tasks.find((function(task){return getLocalizedLinkFromTask(task)===selectedLink}))},setSelection:function(newSelection){taskSelectionInput.value=newSelection,updateName()},setIsGraded:function(isGraded){var disabled;null===isGraded&&(isGradedElem.value=null),isGradedElem.value=isGraded?"1":"0",disabled="0"===isGradedElem.value,document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_duedate_enabled").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled},getGradingType:function(){var isGraded=isGradedElem.value;return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"}}}(),multiTaskEditController=(propertySelectionInputs=document.getElementsByName("mumie_multi_edit_property"),selectedTaskProperties=document.getElementsByName("mumie_selected_task_properties")[0],selectedTaskProp=[],taskSelectionInputs=document.getElementsByName("mumie_multi_edit_task"),selectedTasks=document.getElementsByName("mumie_selected_tasks")[0],selectedTaskIds=[],sectionInputs=document.getElementsByName("mumie_multi_edit_section"),{init:function(){taskSelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskIds.push(checkbox.value):selectedTaskIds=selectedTaskIds.filter((function(elem){return elem!==checkbox.value})),selectedTasks.value=JSON.stringify(selectedTaskIds)}})),propertySelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskProp.push(checkbox.value):selectedTaskProp=selectedTaskProp.filter((function(elem){return elem!==checkbox.value})),selectedTaskProperties.value=JSON.stringify(selectedTaskProp)}})),sectionInputs.forEach((function(sectionCheckbox){sectionCheckbox.onchange=function(){sectionCheckbox.checked?taskSelectionInputs.forEach((function(taskCheckbox){var array,element;taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!0,array=selectedTaskIds,element=taskCheckbox.value,array.includes(element)||array.push(element))})):taskSelectionInputs.forEach((function(taskCheckbox){taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!1,selectedTaskIds=selectedTaskIds.filter((function(elem){return taskCheckbox.value!==elem})))})),selectedTasks.value=JSON.stringify(selectedTaskIds)}}))}});function disableDropDownMenus(errorKey){require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:errorKey,component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0]+""+missingConfig.getAttribute("value")+"",type:"problem"})})).fail(notification.exception)})),serverController.disable(),problemSelectorController.disable()}return{init:function(contextid,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang;var isEdit=document.getElementById("id_name").getAttribute("value"),serverStructure=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);isEdit&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?disableDropDownMenus("mumie_form_missing_server"):serverStructure.length?(serverController.init(serverStructure),courseController.init(),taskController.init(isEdit),multiTaskEditController.init(),problemSelectorController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextid)}))}}})); +define("mod_mumie/mod_form",["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],(function(){const addServerButton=document.getElementById("id_add_server_button"),missingConfig=document.getElementsByName("mumie_missing_config")[0];let lmsSelectorUrl,systemLanguage;const serverController=function(){let serverStructure;const serverDropDown=document.getElementById("id_server");return{init:function(structure){serverStructure=structure},getSelectedServer:function(){const selectedServerName=serverDropDown.options[serverDropDown.selectedIndex].text;return serverStructure.find((server=>server.name===selectedServerName))},disable:function(){serverDropDown.disabled=!0,function(elem){for(;elem.firstChild;)elem.removeChild(elem.firstChild)}(serverDropDown)},getAllServers:function(){return serverStructure}}}(),problemSelectorController=function(){const problemSelectorButton=document.getElementById("id_prb_selector_btn"),multiProblemSelectorButton=document.getElementById("id_multi_problem_selector_btn");let problemSelectorWindow;const mumieOrg=document.getElementsByName("mumie_org")[0].value;function sendResponse(response){problemSelectorWindow&&problemSelectorWindow.postMessage(JSON.stringify(response),lmsSelectorUrl)}function sendSuccess(){let message=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";sendResponse({success:!0,message:message})}function addMessageListener(){window.addEventListener("message",(event=>{if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link+"?lang="+importObj.language),taskController.setIsGraded(isGraded),sendSuccess(),window.focus(),require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0],type:"info"})})).fail(notification.exception)}))}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}return{init:function(){const gradingType=taskController.getGradingType();problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true","_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}(),courseController=function(){const courseNameElem=document.getElementById("id_mumie_course"),coursefileElem=document.getElementsByName("mumie_coursefile")[0];function updateCourseName(){var _selectedCourse$name$;const selectedCourse=courseController.getSelectedCourse(),selectedLanguage=langController.getSelectedLanguage();selectedCourse&&selectedLanguage&&(courseNameElem.value=null===(_selectedCourse$name$=selectedCourse.name.find((translation=>translation.language===selectedLanguage)))||void 0===_selectedCourse$name$?void 0:_selectedCourse$name$.value)}return{init:function(){updateCourseName()},getSelectedCourse:function(){return serverController.getSelectedServer().courses.find((course=>course.coursefile===coursefileElem.value))},updateCourseName:function(){updateCourseName()},setCourse:function(courseFile){var coursefile;coursefile=courseFile,coursefileElem.value=coursefile,updateCourseName()}}}(),langController=function(){const languageElem=document.getElementById("id_language");return{getSelectedLanguage:function(){return languageElem.value},setLanguage:function(lang){if(!function(lang){return courseController.getSelectedCourse().languages.includes(lang)}(lang))throw new Error("Selected language not available");languageElem.value=lang,courseController.updateCourseName()}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element"),isGradedElem=document.getElementById("id_mumie_isgraded");function updateName(){const newHeadline=function(task){if(!task)return null;const selectedLanguage=langController.getSelectedLanguage(),headlineWrapper=task.headline.find((localHeadline=>localHeadline.language===selectedLanguage));return headlineWrapper?headlineWrapper.name:null}(taskController.getSelectedTask());(function(){if(0===nameElem.value.length)return!1;return!serverController.getAllServers().flatMap((server=>server.courses)).flatMap((course=>course.tasks)).flatMap((task=>task.headline)).map((headline=>headline.name)).concat(courseController.getSelectedCourse().name.map((n=>n.value))).includes(nameElem.value)})()||(nameElem.value=newHeadline),taskDisplayElement.value=newHeadline}function getLocalizedLinkFromTask(task){return task.link+"?lang="+langController.getSelectedLanguage()}return{init:function(){updateName()},getSelectedTask:function(){const selectedLink=taskSelectionInput.value,selectedCourse=courseController.getSelectedCourse();if(!selectedCourse)return null;const tasks=selectedCourse.tasks.slice();return tasks.push(function(course){var headline=[];for(var i in course.name){var name=course.name[i];headline.push({name:name.value,language:name.language})}return{link:course.link,headline:headline}}(selectedCourse)),tasks.find((task=>getLocalizedLinkFromTask(task)===selectedLink))},setSelection:function(newSelection){taskSelectionInput.value=newSelection,updateName()},setIsGraded:function(isGraded){null===isGraded&&(isGradedElem.value=null),isGradedElem.value=isGraded?"1":"0",function(){const disabled="0"===isGradedElem.value;document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_duedate_enabled").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled}()},getGradingType:function(){const isGraded=isGradedElem.value;return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"}}}(),multiTaskEditController=function(){const propertySelectionInputs=document.getElementsByName("mumie_multi_edit_property"),selectedTaskProperties=document.getElementsByName("mumie_selected_task_properties")[0];let selectedTaskProp=[];const taskSelectionInputs=document.getElementsByName("mumie_multi_edit_task"),selectedTasks=document.getElementsByName("mumie_selected_tasks")[0];let selectedTaskIds=[];const sectionInputs=document.getElementsByName("mumie_multi_edit_section");return{init:function(){taskSelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskIds.push(checkbox.value):selectedTaskIds=selectedTaskIds.filter((elem=>elem!==checkbox.value)),selectedTasks.value=JSON.stringify(selectedTaskIds)}})),propertySelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskProp.push(checkbox.value):selectedTaskProp=selectedTaskProp.filter((elem=>elem!==checkbox.value)),selectedTaskProperties.value=JSON.stringify(selectedTaskProp)}})),sectionInputs.forEach((function(sectionCheckbox){sectionCheckbox.onchange=function(){sectionCheckbox.checked?taskSelectionInputs.forEach((function(taskCheckbox){var array,element;taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!0,array=selectedTaskIds,element=taskCheckbox.value,array.includes(element)||array.push(element))})):taskSelectionInputs.forEach((function(taskCheckbox){taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!1,selectedTaskIds=selectedTaskIds.filter((elem=>taskCheckbox.value!==elem)))})),selectedTasks.value=JSON.stringify(selectedTaskIds)}}))}}}();function disableDropDownMenus(errorKey){require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:errorKey,component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0]+""+missingConfig.getAttribute("value")+"",type:"problem"})})).fail(notification.exception)})),serverController.disable(),problemSelectorController.disable()}return{init:function(contextid,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang;const isEdit=document.getElementById("id_name").getAttribute("value"),serverStructure=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);isEdit&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?disableDropDownMenus("mumie_form_missing_server"):serverStructure.length?(serverController.init(serverStructure),courseController.init(),taskController.init(isEdit),multiTaskEditController.init(),problemSelectorController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextid)}))}}})); //# sourceMappingURL=mod_form.min.js.map \ No newline at end of file diff --git a/amd/build/mod_form.min.js.map b/amd/build/mod_form.min.js.map index 6848302..ca3ed7c 100644 --- a/amd/build/mod_form.min.js.map +++ b/amd/build/mod_form.min.js.map @@ -1 +1 @@ -{"version":3,"file":"mod_form.min.js","sources":["../src/mod_form.js"],"sourcesContent":["define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_server_config', 'core/ajax'],\n function() {\n const addServerButton = document.getElementById(\"id_add_server_button\");\n const missingConfig = document.getElementsByName(\"mumie_missing_config\")[0];\n let lmsSelectorUrl;\n let systemLanguage;\n const serverController = (function() {\n let serverStructure;\n const serverDropDown = document.getElementById(\"id_server\");\n\n return {\n init: function(structure) {\n serverStructure = structure;\n },\n getSelectedServer: function() {\n const selectedServerName = serverDropDown.options[serverDropDown.selectedIndex].text;\n return serverStructure.find(server => server.name === selectedServerName);\n },\n disable: function() {\n serverDropDown.disabled = true;\n removeChildElems(serverDropDown);\n },\n getAllServers: function() {\n return serverStructure;\n }\n };\n })();\n\n const problemSelectorController = (function() {\n const problemSelectorButton = document.getElementById('id_prb_selector_btn');\n let problemSelectorWindow;\n const mumieOrg = document.getElementsByName('mumie_org')[0].value;\n\n /**\n * Send a message to the problem selector window.\n *\n * Don't do anything, if there is no problem selector window.\n * @param {Object} response\n */\n function sendResponse(response) {\n if (!problemSelectorWindow) {\n return;\n }\n problemSelectorWindow.postMessage(JSON.stringify(response), lmsSelectorUrl);\n }\n\n /**\n * Send a success message to problem selector window\n * @param {string} message\n */\n function sendSuccess(message = '') {\n sendResponse({\n success: true,\n message: message\n });\n }\n\n /**\n * Send a failure message to problem selector window\n * @param {string} message\n */\n function sendFailure(message = '') {\n sendResponse({\n success: false,\n message: message\n });\n }\n\n /**\n * Add an event listener that accepts messages from LMS-Browser and updates the selected problem.\n */\n function addMessageListener() {\n window.addEventListener('message', (event) => {\n if (event.origin !== lmsSelectorUrl) {\n return;\n }\n const importObj = JSON.parse(event.data);\n const isGraded = importObj.isGraded !== false;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link + '?lang=' + importObj.language);\n taskController.setIsGraded(isGraded);\n sendSuccess();\n window.focus();\n displayProblemSelectedMessage();\n } catch (error) {\n sendFailure(error.message);\n }\n }, false);\n }\n\n /**\n * Display a success message in Moodle that a problem was successfully selected.\n */\n function displayProblemSelectedMessage() {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': 'mumie_form_updated_selection',\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0],\n type: \"info\"\n });\n }).fail(notification.exception);\n });\n }\n\n return {\n init: function() {\n const gradingType = taskController.getGradingType();\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + 'org='\n + mumieOrg\n + '&serverUrl='\n + encodeURIComponent(serverController.getSelectedServer().urlprefix)\n + '&problemLang='\n + langController.getSelectedLanguage()\n + '&origin=' + encodeURIComponent(window.location.origin)\n + '&uiLang=' + systemLanguage\n + '&gradingType=' + gradingType\n + '&multiCourse=true'\n , '_blank'\n );\n };\n\n window.onclose = function() {\n sendSuccess();\n };\n\n window.addEventListener(\"beforeunload\", function() {\n sendSuccess();\n }, false);\n\n addMessageListener();\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n }\n };\n })();\n\n const courseController = (function() {\n const courseNameElem = document.getElementById(\"id_mumie_course\");\n const coursefileElem = document.getElementsByName(\"mumie_coursefile\")[0];\n\n\n /**\n * Update the hidden input field with the selected course's course file path\n *\n * @param {string} coursefile\n */\n function updateCoursefilePath(coursefile) {\n coursefileElem.value = coursefile;\n updateCourseName();\n }\n\n /**\n * Update displayed course name.\n */\n function updateCourseName() {\n const selectedCourse = courseController.getSelectedCourse();\n const selectedLanguage = langController.getSelectedLanguage();\n if (!selectedCourse || !selectedLanguage) {\n return;\n }\n courseNameElem.value = selectedCourse.name\n .find(translation => translation.language === selectedLanguage)?.value;\n }\n\n return {\n init: function() {\n updateCourseName();\n },\n getSelectedCourse: function() {\n const courses = serverController.getSelectedServer().courses;\n return courses.find(course => course.coursefile === coursefileElem.value);\n },\n updateCourseName: function() {\n updateCourseName();\n },\n setCourse: function(courseFile) {\n updateCoursefilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n\n /**\n * Check if the given language exists in the currently selected course.\n * @param {string} lang\n * @returns {boolean} Whether the language exists\n */\n function languageExists(lang) {\n return courseController.getSelectedCourse().languages.includes(lang);\n }\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n if (!languageExists(lang)) {\n throw new Error(\"Selected language not available\");\n }\n languageElem.value = lang;\n courseController.updateCourseName();\n }\n };\n })();\n\n const taskController = (function() {\n const taskSelectionInput = document.getElementsByName(\"taskurl\")[0];\n const nameElem = document.getElementById(\"id_name\");\n const taskDisplayElement = document.getElementById(\"id_task_display_element\");\n const isGradedElem = document.getElementById('id_mumie_isgraded');\n\n\n /**\n * Update the activity's name in the input field\n */\n function updateName() {\n const newHeadline = getHeadline(taskController.getSelectedTask());\n if (!isCustomName()) {\n nameElem.value = newHeadline;\n }\n taskDisplayElement.value = newHeadline;\n }\n\n /**\n * Check whether the activity has a custom name\n *\n * @return {boolean} True, if there is no headline with that name in all tasks\n */\n function isCustomName() {\n if (nameElem.value.length === 0) {\n return false;\n }\n return !getAllHeadlines().includes(nameElem.value);\n }\n\n /**\n * Get the task's headline for the currently selected language\n * @param {Object} task\n * @returns {string|null} the headline\n */\n function getHeadline(task) {\n if (!task) {\n return null;\n }\n const selectedLanguage = langController.getSelectedLanguage();\n const headlineWrapper = task.headline.find(localHeadline => localHeadline.language === selectedLanguage);\n return headlineWrapper ? headlineWrapper.name : null;\n }\n\n /**\n * Get all tasks that are available on all servers\n *\n * @return {Object} Array containing all available tasks\n */\n function getAllTasks() {\n return serverController.getAllServers()\n .flatMap(server => server.courses)\n .flatMap(course => course.tasks);\n }\n\n /**\n * Get all possible headlines in all languages\n * @returns {Object} Array containing all headlines\n */\n function getAllHeadlines() {\n return getAllTasks().flatMap(task => task.headline)\n .map(headline => headline.name)\n .concat(courseController.getSelectedCourse().name.map(n => n.value));\n }\n\n /**\n * Add language parameter to the task's link to display content in the selected language\n * @param {Object} task\n * @returns {string}\n */\n function getLocalizedLinkFromTask(task) {\n return getLocalizedLink(task.link);\n }\n\n /**\n * Add language parameter to link\n * @param {string} link\n * @returns {string}\n */\n function getLocalizedLink(link) {\n return link + \"?lang=\" + langController.getSelectedLanguage();\n }\n\n /**\n * Form inputs related to grades should be disabled, if the MUMIE Task is not graded.\n */\n function updateGradeEditability() {\n const disabled = isGradedElem.value === '0';\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_duedate_enabled').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n }\n\n /**\n * Get a task that links to a course's overview page\n * @param {Object} course\n * @returns {Object} task\n */\n function getPseudoTaskFromCourse(course) {\n var headline = [];\n for (var i in course.name) {\n var name = course.name[i];\n headline.push({\n \"name\": name.value,\n \"language\": name.language\n });\n }\n return {\n \"link\": course.link,\n \"headline\": headline\n };\n }\n\n return {\n init: function() {\n updateName();\n },\n getSelectedTask: function() {\n const selectedLink = taskSelectionInput.value;\n const selectedCourse = courseController.getSelectedCourse();\n if (!selectedCourse) {\n return null;\n }\n const tasks = selectedCourse\n .tasks\n .slice();\n tasks.push(getPseudoTaskFromCourse(selectedCourse));\n return tasks\n .find(task => getLocalizedLinkFromTask(task) === selectedLink);\n },\n setSelection: function(newSelection) {\n taskSelectionInput.value = newSelection;\n updateName();\n },\n setIsGraded: function(isGraded) {\n if (isGraded === null) {\n isGradedElem.value = null;\n }\n isGradedElem.value = isGraded ? '1' : '0';\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = isGradedElem.value;\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n }\n };\n })();\n\n\n const multiTaskEditController = (function() {\n const propertySelectionInputs = document.getElementsByName(\"mumie_multi_edit_property\");\n const selectedTaskProperties = document.getElementsByName(\"mumie_selected_task_properties\")[0];\n let selectedTaskProp = [];\n const taskSelectionInputs = document.getElementsByName(\"mumie_multi_edit_task\");\n const selectedTasks = document.getElementsByName(\"mumie_selected_tasks\")[0];\n let selectedTaskIds = [];\n const sectionInputs = document.getElementsByName(\"mumie_multi_edit_section\");\n\n /**\n * Push an element to an array, if it's not already included.\n *\n * @param {string[]} array\n * @param {string} element\n */\n function pushIfNotExists(array, element) {\n if (!array.includes(element)) {\n array.push(element);\n }\n }\n\n /**\n * Set selection listeners for other MUMIE Tasks in the course.\n */\n function setTaskSelectionListeners() {\n taskSelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskIds = selectedTaskIds.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskIds.push(checkbox.value);\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n /**\n * Set selection listeners for properties to apply to MUMIE Tasks in the course.\n */\n function setPropertySelectionListeners() {\n propertySelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskProp = selectedTaskProp.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskProp.push(checkbox.value);\n }\n selectedTaskProperties.value = JSON.stringify(selectedTaskProp);\n };\n });\n }\n\n /**\n * Set selection listeners for entire section of MUMIE Tasks in the course\n */\n function setSectionSelectionListeners() {\n sectionInputs.forEach(function(sectionCheckbox) {\n sectionCheckbox.onchange = function() {\n if (!sectionCheckbox.checked) {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = false;\n selectedTaskIds = selectedTaskIds.filter(elem => taskCheckbox.value !== elem);\n }\n });\n } else {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = true;\n pushIfNotExists(selectedTaskIds, taskCheckbox.value);\n }\n });\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n return {\n init: function() {\n setTaskSelectionListeners();\n setPropertySelectionListeners();\n setSectionSelectionListeners();\n },\n };\n })();\n\n /**\n * Disable all dropdown menus and show notification\n * @param {string} errorKey\n */\n function disableDropDownMenus(errorKey) {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': errorKey,\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0] + \"\" + missingConfig.getAttribute(\"value\") + \"\",\n type: \"problem\"\n });\n }).fail(notification.exception);\n });\n serverController.disable();\n problemSelectorController.disable();\n }\n\n return {\n init: function(contextid, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n const isEdit = document.getElementById(\"id_name\").getAttribute('value');\n const serverStructure = JSON.parse(document.getElementsByName('mumie_server_structure')[0].value);\n if (isEdit && !serverConfigExists()) {\n disableDropDownMenus('mumie_form_missing_server');\n } else if (!serverStructure.length) {\n disableDropDownMenus('mumie_form_no_server_conf');\n } else {\n serverController.init(serverStructure);\n courseController.init();\n taskController.init(isEdit);\n multiTaskEditController.init();\n problemSelectorController.init();\n }\n multiTaskEditController.init();\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextid);\n });\n }\n }\n };\n\n /**\n * Remove all child elements of a given html element\n * @param {Object} elem\n */\n function removeChildElems(elem) {\n while (elem.firstChild) {\n elem.removeChild(elem.firstChild);\n }\n }\n\n /**\n * Check, if the flag for an existing config is set\n * @returns {boolean}\n */\n function serverConfigExists() {\n return document.getElementsByName(\"mumie_missing_config\")[0].getAttribute(\"value\") === \"\";\n }\n });\n"],"names":["define","lmsSelectorUrl","systemLanguage","serverStructure","serverDropDown","languageElem","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","addServerButton","document","getElementById","missingConfig","getElementsByName","serverController","init","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","getAllServers","problemSelectorController","problemSelectorWindow","problemSelectorButton","mumieOrg","value","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","window","addEventListener","event","origin","importObj","parse","data","isGraded","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","gradingType","getGradingType","onclick","open","encodeURIComponent","urlprefix","getSelectedLanguage","location","onclose","courseNameElem","coursefileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","lang","languages","includes","languageExists","Error","taskSelectionInput","nameElem","taskDisplayElement","isGradedElem","updateName","newHeadline","task","headlineWrapper","headline","localHeadline","getHeadline","getSelectedTask","length","flatMap","tasks","map","concat","n","isCustomName","getLocalizedLinkFromTask","selectedLink","slice","push","i","getPseudoTaskFromCourse","newSelection","multiTaskEditController","forEach","checkbox","onchange","checked","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","disableDropDownMenus","errorKey","contextid","prbSelectorUrl","isEdit","MumieServer"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"mod_form.min.js","sources":["../src/mod_form.js"],"sourcesContent":["define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_server_config', 'core/ajax'],\n function() {\n const addServerButton = document.getElementById(\"id_add_server_button\");\n const missingConfig = document.getElementsByName(\"mumie_missing_config\")[0];\n let lmsSelectorUrl;\n let systemLanguage;\n const serverController = (function() {\n let serverStructure;\n const serverDropDown = document.getElementById(\"id_server\");\n\n return {\n init: function(structure) {\n serverStructure = structure;\n },\n getSelectedServer: function() {\n const selectedServerName = serverDropDown.options[serverDropDown.selectedIndex].text;\n return serverStructure.find(server => server.name === selectedServerName);\n },\n disable: function() {\n serverDropDown.disabled = true;\n removeChildElems(serverDropDown);\n },\n getAllServers: function() {\n return serverStructure;\n }\n };\n })();\n\n const problemSelectorController = (function() {\n const problemSelectorButton = document.getElementById('id_prb_selector_btn');\n const multiProblemSelectorButton = document.getElementById('id_multi_problem_selector_btn');\n let problemSelectorWindow;\n const mumieOrg = document.getElementsByName('mumie_org')[0].value;\n\n /**\n * Send a message to the problem selector window.\n *\n * Don't do anything, if there is no problem selector window.\n * @param {Object} response\n */\n function sendResponse(response) {\n if (!problemSelectorWindow) {\n return;\n }\n problemSelectorWindow.postMessage(JSON.stringify(response), lmsSelectorUrl);\n }\n\n /**\n * Send a success message to problem selector window\n * @param {string} message\n */\n function sendSuccess(message = '') {\n sendResponse({\n success: true,\n message: message\n });\n }\n\n /**\n * Send a failure message to problem selector window\n * @param {string} message\n */\n function sendFailure(message = '') {\n sendResponse({\n success: false,\n message: message\n });\n }\n\n /**\n * Add an event listener that accepts messages from LMS-Browser and updates the selected problem.\n */\n function addMessageListener() {\n window.addEventListener('message', (event) => {\n if (event.origin !== lmsSelectorUrl) {\n return;\n }\n const importObj = JSON.parse(event.data);\n const isGraded = importObj.isGraded !== false;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link + '?lang=' + importObj.language);\n taskController.setIsGraded(isGraded);\n sendSuccess();\n window.focus();\n displayProblemSelectedMessage();\n } catch (error) {\n sendFailure(error.message);\n }\n }, false);\n }\n\n /**\n * Display a success message in Moodle that a problem was successfully selected.\n */\n function displayProblemSelectedMessage() {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': 'mumie_form_updated_selection',\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0],\n type: \"info\"\n });\n }).fail(notification.exception);\n });\n }\n\n return {\n init: function() {\n const gradingType = taskController.getGradingType();\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + 'org='\n + mumieOrg\n + '&serverUrl='\n + encodeURIComponent(serverController.getSelectedServer().urlprefix)\n + '&problemLang='\n + langController.getSelectedLanguage()\n + '&origin=' + encodeURIComponent(window.location.origin)\n + '&uiLang=' + systemLanguage\n + '&gradingType=' + gradingType\n + '&multiCourse=true'\n , '_blank'\n );\n };\n\n window.onclose = function() {\n sendSuccess();\n };\n\n window.addEventListener(\"beforeunload\", function() {\n sendSuccess();\n }, false);\n\n addMessageListener();\n\n multiProblemSelectorButton.onclick = function(e) {\n e.preventDefault();\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + \"serverUrl=\"\n + encodeURIComponent(serverController.getSelectedServer().urlprefix),\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n }\n };\n })();\n\n const courseController = (function() {\n const courseNameElem = document.getElementById(\"id_mumie_course\");\n const coursefileElem = document.getElementsByName(\"mumie_coursefile\")[0];\n\n\n /**\n * Update the hidden input field with the selected course's course file path\n *\n * @param {string} coursefile\n */\n function updateCoursefilePath(coursefile) {\n coursefileElem.value = coursefile;\n updateCourseName();\n }\n\n /**\n * Update displayed course name.\n */\n function updateCourseName() {\n const selectedCourse = courseController.getSelectedCourse();\n const selectedLanguage = langController.getSelectedLanguage();\n if (!selectedCourse || !selectedLanguage) {\n return;\n }\n courseNameElem.value = selectedCourse.name\n .find(translation => translation.language === selectedLanguage)?.value;\n }\n\n return {\n init: function() {\n updateCourseName();\n },\n getSelectedCourse: function() {\n const courses = serverController.getSelectedServer().courses;\n return courses.find(course => course.coursefile === coursefileElem.value);\n },\n updateCourseName: function() {\n updateCourseName();\n },\n setCourse: function(courseFile) {\n updateCoursefilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n\n /**\n * Check if the given language exists in the currently selected course.\n * @param {string} lang\n * @returns {boolean} Whether the language exists\n */\n function languageExists(lang) {\n return courseController.getSelectedCourse().languages.includes(lang);\n }\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n if (!languageExists(lang)) {\n throw new Error(\"Selected language not available\");\n }\n languageElem.value = lang;\n courseController.updateCourseName();\n }\n };\n })();\n\n const taskController = (function() {\n const taskSelectionInput = document.getElementsByName(\"taskurl\")[0];\n const nameElem = document.getElementById(\"id_name\");\n const taskDisplayElement = document.getElementById(\"id_task_display_element\");\n const isGradedElem = document.getElementById('id_mumie_isgraded');\n\n\n /**\n * Update the activity's name in the input field\n */\n function updateName() {\n const newHeadline = getHeadline(taskController.getSelectedTask());\n if (!isCustomName()) {\n nameElem.value = newHeadline;\n }\n taskDisplayElement.value = newHeadline;\n }\n\n /**\n * Check whether the activity has a custom name\n *\n * @return {boolean} True, if there is no headline with that name in all tasks\n */\n function isCustomName() {\n if (nameElem.value.length === 0) {\n return false;\n }\n return !getAllHeadlines().includes(nameElem.value);\n }\n\n /**\n * Get the task's headline for the currently selected language\n * @param {Object} task\n * @returns {string|null} the headline\n */\n function getHeadline(task) {\n if (!task) {\n return null;\n }\n const selectedLanguage = langController.getSelectedLanguage();\n const headlineWrapper = task.headline.find(localHeadline => localHeadline.language === selectedLanguage);\n return headlineWrapper ? headlineWrapper.name : null;\n }\n\n /**\n * Get all tasks that are available on all servers\n *\n * @return {Object} Array containing all available tasks\n */\n function getAllTasks() {\n return serverController.getAllServers()\n .flatMap(server => server.courses)\n .flatMap(course => course.tasks);\n }\n\n /**\n * Get all possible headlines in all languages\n * @returns {Object} Array containing all headlines\n */\n function getAllHeadlines() {\n return getAllTasks().flatMap(task => task.headline)\n .map(headline => headline.name)\n .concat(courseController.getSelectedCourse().name.map(n => n.value));\n }\n\n /**\n * Add language parameter to the task's link to display content in the selected language\n * @param {Object} task\n * @returns {string}\n */\n function getLocalizedLinkFromTask(task) {\n return getLocalizedLink(task.link);\n }\n\n /**\n * Add language parameter to link\n * @param {string} link\n * @returns {string}\n */\n function getLocalizedLink(link) {\n return link + \"?lang=\" + langController.getSelectedLanguage();\n }\n\n /**\n * Form inputs related to grades should be disabled, if the MUMIE Task is not graded.\n */\n function updateGradeEditability() {\n const disabled = isGradedElem.value === '0';\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_duedate_enabled').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n }\n\n /**\n * Get a task that links to a course's overview page\n * @param {Object} course\n * @returns {Object} task\n */\n function getPseudoTaskFromCourse(course) {\n var headline = [];\n for (var i in course.name) {\n var name = course.name[i];\n headline.push({\n \"name\": name.value,\n \"language\": name.language\n });\n }\n return {\n \"link\": course.link,\n \"headline\": headline\n };\n }\n\n return {\n init: function() {\n updateName();\n },\n getSelectedTask: function() {\n const selectedLink = taskSelectionInput.value;\n const selectedCourse = courseController.getSelectedCourse();\n if (!selectedCourse) {\n return null;\n }\n const tasks = selectedCourse\n .tasks\n .slice();\n tasks.push(getPseudoTaskFromCourse(selectedCourse));\n return tasks\n .find(task => getLocalizedLinkFromTask(task) === selectedLink);\n },\n setSelection: function(newSelection) {\n taskSelectionInput.value = newSelection;\n updateName();\n },\n setIsGraded: function(isGraded) {\n if (isGraded === null) {\n isGradedElem.value = null;\n }\n isGradedElem.value = isGraded ? '1' : '0';\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = isGradedElem.value;\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n }\n };\n })();\n\n\n const multiTaskEditController = (function() {\n const propertySelectionInputs = document.getElementsByName(\"mumie_multi_edit_property\");\n const selectedTaskProperties = document.getElementsByName(\"mumie_selected_task_properties\")[0];\n let selectedTaskProp = [];\n const taskSelectionInputs = document.getElementsByName(\"mumie_multi_edit_task\");\n const selectedTasks = document.getElementsByName(\"mumie_selected_tasks\")[0];\n let selectedTaskIds = [];\n const sectionInputs = document.getElementsByName(\"mumie_multi_edit_section\");\n\n /**\n * Push an element to an array, if it's not already included.\n *\n * @param {string[]} array\n * @param {string} element\n */\n function pushIfNotExists(array, element) {\n if (!array.includes(element)) {\n array.push(element);\n }\n }\n\n /**\n * Set selection listeners for other MUMIE Tasks in the course.\n */\n function setTaskSelectionListeners() {\n taskSelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskIds = selectedTaskIds.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskIds.push(checkbox.value);\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n /**\n * Set selection listeners for properties to apply to MUMIE Tasks in the course.\n */\n function setPropertySelectionListeners() {\n propertySelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskProp = selectedTaskProp.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskProp.push(checkbox.value);\n }\n selectedTaskProperties.value = JSON.stringify(selectedTaskProp);\n };\n });\n }\n\n /**\n * Set selection listeners for entire section of MUMIE Tasks in the course\n */\n function setSectionSelectionListeners() {\n sectionInputs.forEach(function(sectionCheckbox) {\n sectionCheckbox.onchange = function() {\n if (!sectionCheckbox.checked) {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = false;\n selectedTaskIds = selectedTaskIds.filter(elem => taskCheckbox.value !== elem);\n }\n });\n } else {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = true;\n pushIfNotExists(selectedTaskIds, taskCheckbox.value);\n }\n });\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n return {\n init: function() {\n setTaskSelectionListeners();\n setPropertySelectionListeners();\n setSectionSelectionListeners();\n },\n };\n })();\n\n /**\n * Disable all dropdown menus and show notification\n * @param {string} errorKey\n */\n function disableDropDownMenus(errorKey) {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': errorKey,\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0] + \"\" + missingConfig.getAttribute(\"value\") + \"\",\n type: \"problem\"\n });\n }).fail(notification.exception);\n });\n serverController.disable();\n problemSelectorController.disable();\n }\n\n return {\n init: function(contextid, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n const isEdit = document.getElementById(\"id_name\").getAttribute('value');\n const serverStructure = JSON.parse(document.getElementsByName('mumie_server_structure')[0].value);\n if (isEdit && !serverConfigExists()) {\n disableDropDownMenus('mumie_form_missing_server');\n } else if (!serverStructure.length) {\n disableDropDownMenus('mumie_form_no_server_conf');\n } else {\n serverController.init(serverStructure);\n courseController.init();\n taskController.init(isEdit);\n multiTaskEditController.init();\n problemSelectorController.init();\n }\n multiTaskEditController.init();\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextid);\n });\n }\n }\n };\n\n /**\n * Remove all child elements of a given html element\n * @param {Object} elem\n */\n function removeChildElems(elem) {\n while (elem.firstChild) {\n elem.removeChild(elem.firstChild);\n }\n }\n\n /**\n * Check, if the flag for an existing config is set\n * @returns {boolean}\n */\n function serverConfigExists() {\n return document.getElementsByName(\"mumie_missing_config\")[0].getAttribute(\"value\") === \"\";\n }\n });\n"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","serverController","serverStructure","serverDropDown","init","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","getAllServers","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","value","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","window","addEventListener","event","origin","importObj","parse","data","isGraded","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","gradingType","getGradingType","onclick","open","encodeURIComponent","urlprefix","getSelectedLanguage","location","onclose","e","preventDefault","courseNameElem","coursefileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","languages","includes","languageExists","Error","taskSelectionInput","nameElem","taskDisplayElement","isGradedElem","updateName","newHeadline","task","headlineWrapper","headline","localHeadline","getHeadline","getSelectedTask","length","flatMap","tasks","map","concat","n","isCustomName","getLocalizedLinkFromTask","selectedLink","slice","push","i","getPseudoTaskFromCourse","newSelection","updateGradeEditability","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","onchange","checked","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","disableDropDownMenus","errorKey","contextid","prbSelectorUrl","isEdit","MumieServer"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 813c6f0..b6a13cb 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -28,6 +28,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv const problemSelectorController = (function() { const problemSelectorButton = document.getElementById('id_prb_selector_btn'); + const multiProblemSelectorButton = document.getElementById('id_multi_problem_selector_btn'); let problemSelectorWindow; const mumieOrg = document.getElementsByName('mumie_org')[0].value; @@ -137,6 +138,18 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }, false); addMessageListener(); + + multiProblemSelectorButton.onclick = function(e) { + e.preventDefault(); + problemSelectorWindow = window.open( + lmsSelectorUrl + + '/lms-problem-selector?' + + "serverUrl=" + + encodeURIComponent(serverController.getSelectedServer().urlprefix), + "_blank", + 'toolbar=0,location=0,menubar=0' + ); + }; }, disable: function() { problemSelectorButton.disabled = true; diff --git a/changelog.md b/changelog.md index 166a7f1..d98239b 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,9 @@ All important changes to this plugin will be documented in this file. ### Changed - Button to open a MUMIE Task in grading view is moved on top of participant list +### Added +- Multiple Problem Selector can now be opened directly from mod_mumie form + ## [v1.4.9] - 2023-01-11 ### Fixed diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 6c24462..65d8f58 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -102,7 +102,8 @@ $string['mumie_form_complete_course'] = 'Ganzen Kurs verlinken'; $string['mumie_form_complete_course_help'] = 'Nutzer werden nur eingeloggt und dann zur Kursübersicht weitergeleitet. Leistungsdaten werden für diese MUMIE-Task nicht synchronisiert.'; $string['mumie_form_launchcontainer_info'] = 'Eingebettete MUMIE-Task führen auf manchen Browsern und Betriebssystemen zu technischen Problemen. Daher empfehlen wir MUMIE-Tasks in einem neuen Fenster zu öffnen.'; -$string['mumie_form_prb_selector_btn'] = 'Aufgabenauswahl öffnen'; +$string['mumie_form_prb_selector_btn'] = 'Aufgabenauswahl'; +$string['mumie_form_multi_prb_selector_btn'] = 'Mehrfach-Aufgabenauswahl'; $string['mumie_form_updated_selection'] = 'Aufgabe erfolgreich ausgewählt'; $string['mumie_form_tasks_edit'] = 'In anderen MUMIE-Tasks übernehmen'; $string['mumie_form_tasks_edit_info'] = 'Sie können einige der oben gewählten Einstellungen auch automatisch in anderen MUMIE-Tasks dieses Kurses übernehmen'; @@ -113,6 +114,7 @@ $string['mumie_no_other_task_found'] = 'Keine andere MUMIE Tasks in Kurs gefunden'; $string['mumie_form_wiki_link'] = 'Bitte besuchen Sie unser Wiki für weiterführende Informationen!'; $string['mumie_form_no_course_on_server'] = 'MUMIE-Server {$a} konnte nicht erreicht werden! Dieser Server wurde daher vorrübergehend aus der Auswahl entfernt.'; +$string['mumie_multi_problem_selector'] = 'Alternativ können Sie auch mehrere MUMIE Tasks gleichzeitig mit der Mehrfach-Aufgabenauswahl erstellen. Ziehen Sie dazu einfach die gewünschten Aufgaben in ihren Kurs.

Für eine Kurzanleitung und weitere Informationen besuchen Sie unser Wiki'; // Used in duedate form. $string['mumie_duedate_form'] = 'Abgabefrist verlängern'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 94b5fe8..85516dd 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -86,7 +86,8 @@ $string['mumie_form_complete_course'] = 'Link the entire course'; $string['mumie_form_complete_course_help'] = 'The user will only be logged in and redirected to the course overview page. Grades will not be synchronized for this MUMIE Task.'; $string['mumie_form_launchcontainer_info'] = 'Embedded MUMIE Tasks tend to cause issues on some browsers and operation systems so we recommend using New-Window-mode.'; -$string['mumie_form_prb_selector_btn'] = 'Open problem selector'; +$string['mumie_form_prb_selector_btn'] = 'Problem selector'; +$string['mumie_form_multi_prb_selector_btn'] = 'Multi Problem Selector'; $string['mumie_form_updated_selection'] = 'Successfully selected problem'; $string['mumie_form_tasks_edit'] = 'Apply to other MUMIE Tasks'; $string['mumie_form_tasks_edit_info'] = 'You can apply some of the settings selected above also automatically to other MUMIE Tasks of this course.'; @@ -97,6 +98,7 @@ $string['mumie_no_other_task_found'] = 'No other MUMIE Tasks found in course'; $string['mumie_form_wiki_link'] = 'For help and advanced features, please visit our Wiki!'; $string['mumie_form_no_course_on_server'] = 'MUMIE server {$a} is not available! Temporarily removed this server from selection.'; +$string['mumie_multi_problem_selector'] = 'Alternatively, you can also create multiple MUMIE Tasks at once simply via Multi Problem Selector by dragging them into your course.

For information on how to use this, have a look at our wiki'; // Used in mumieserver form. $string['mumie_form_required'] = 'required'; diff --git a/mod_form.php b/mod_form.php index e93e3c5..997fc64 100644 --- a/mod_form.php +++ b/mod_form.php @@ -109,6 +109,13 @@ public function definition() { $mform->setType("task_display_element", PARAM_TEXT); $contentbutton = $mform->addElement('button', 'prb_selector_btn', get_string('mumie_form_prb_selector_btn', 'mod_mumie')); + $wiki_link = 'https://wiki.mumie.net/wiki/MUMIE-Moodle-integration-for-teachers#how-to-create-mumie-tasks-with-drag-and-drop'; + $this->add_info_box( + get_string( + "mumie_multi_problem_selector", + "mod_mumie", + $wiki_link)); + $mform->addElement('button', 'multi_problem_selector_btn', get_string('mumie_form_multi_prb_selector_btn', 'mod_mumie')); $launchoptions = array(); $launchoptions[MUMIE_LAUNCH_CONTAINER_EMBEDDED] = get_string("mumie_form_activity_container_embedded", "mod_mumie"); diff --git a/version.php b/version.php index 2ef4cb8..4e81cbd 100644 --- a/version.php +++ b/version.php @@ -25,9 +25,9 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2023011100; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2023021311; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). -$plugin->requires = 2020061500; +$plugin->requires = 2022041900; $plugin->release = "v1.4.9"; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = array( From aad2a024ae195357e00025fc2f7881811a29fd94 Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 23 Feb 2023 17:05:17 +0100 Subject: [PATCH 04/10] Fixing pipeline and updating changelog --- .github/workflows/main.yml | 9 +++------ changelog.md | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 40445fa..5a28b34 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,14 +19,11 @@ jobs: moodle-branch: 'master' database: 'pgsql' - php: '7.4' - moodle-branch: 'MOODLE_311_STABLE' + moodle-branch: 'MOODLE_401_STABLE' database: 'mariadb' - - php: '7.3' - moodle-branch: 'MOODLE_310_STABLE' + - php: '7.4' + moodle-branch: 'MOODLE_400_STABLE' database: 'pgsql' - - php: '7.2' - moodle-branch: 'MOODLE_39_STABLE' - database: 'mariadb' services: postgres: diff --git a/changelog.md b/changelog.md index d98239b..2f2caf5 100644 --- a/changelog.md +++ b/changelog.md @@ -5,10 +5,10 @@ All important changes to this plugin will be documented in this file. ## [v1.4.10] - TODO ### Changed -- Button to open a MUMIE Task in grading view is moved on top of participant list +- Button to open a MUMIE Task in grading view is moved on top of the participant list ### Added -- Multiple Problem Selector can now be opened directly from mod_mumie form +- The Multiple Problem Selector can now be opened directly from mod_mumie form ## [v1.4.9] - 2023-01-11 From 6d34a38bd5f1fbe32760094cf90856ce78491c2e Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 23 Feb 2023 17:06:38 +0100 Subject: [PATCH 05/10] Updated stale minified js files --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 9e7bba6..29f38fa 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1,3 +1,3 @@ -define("mod_mumie/mod_form",["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],(function(){const addServerButton=document.getElementById("id_add_server_button"),missingConfig=document.getElementsByName("mumie_missing_config")[0];let lmsSelectorUrl,systemLanguage;const serverController=function(){let serverStructure;const serverDropDown=document.getElementById("id_server");return{init:function(structure){serverStructure=structure},getSelectedServer:function(){const selectedServerName=serverDropDown.options[serverDropDown.selectedIndex].text;return serverStructure.find((server=>server.name===selectedServerName))},disable:function(){serverDropDown.disabled=!0,function(elem){for(;elem.firstChild;)elem.removeChild(elem.firstChild)}(serverDropDown)},getAllServers:function(){return serverStructure}}}(),problemSelectorController=function(){const problemSelectorButton=document.getElementById("id_prb_selector_btn"),multiProblemSelectorButton=document.getElementById("id_multi_problem_selector_btn");let problemSelectorWindow;const mumieOrg=document.getElementsByName("mumie_org")[0].value;function sendResponse(response){problemSelectorWindow&&problemSelectorWindow.postMessage(JSON.stringify(response),lmsSelectorUrl)}function sendSuccess(){let message=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";sendResponse({success:!0,message:message})}function addMessageListener(){window.addEventListener("message",(event=>{if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link+"?lang="+importObj.language),taskController.setIsGraded(isGraded),sendSuccess(),window.focus(),require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0],type:"info"})})).fail(notification.exception)}))}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}return{init:function(){const gradingType=taskController.getGradingType();problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true","_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}(),courseController=function(){const courseNameElem=document.getElementById("id_mumie_course"),coursefileElem=document.getElementsByName("mumie_coursefile")[0];function updateCourseName(){var _selectedCourse$name$;const selectedCourse=courseController.getSelectedCourse(),selectedLanguage=langController.getSelectedLanguage();selectedCourse&&selectedLanguage&&(courseNameElem.value=null===(_selectedCourse$name$=selectedCourse.name.find((translation=>translation.language===selectedLanguage)))||void 0===_selectedCourse$name$?void 0:_selectedCourse$name$.value)}return{init:function(){updateCourseName()},getSelectedCourse:function(){return serverController.getSelectedServer().courses.find((course=>course.coursefile===coursefileElem.value))},updateCourseName:function(){updateCourseName()},setCourse:function(courseFile){var coursefile;coursefile=courseFile,coursefileElem.value=coursefile,updateCourseName()}}}(),langController=function(){const languageElem=document.getElementById("id_language");return{getSelectedLanguage:function(){return languageElem.value},setLanguage:function(lang){if(!function(lang){return courseController.getSelectedCourse().languages.includes(lang)}(lang))throw new Error("Selected language not available");languageElem.value=lang,courseController.updateCourseName()}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element"),isGradedElem=document.getElementById("id_mumie_isgraded");function updateName(){const newHeadline=function(task){if(!task)return null;const selectedLanguage=langController.getSelectedLanguage(),headlineWrapper=task.headline.find((localHeadline=>localHeadline.language===selectedLanguage));return headlineWrapper?headlineWrapper.name:null}(taskController.getSelectedTask());(function(){if(0===nameElem.value.length)return!1;return!serverController.getAllServers().flatMap((server=>server.courses)).flatMap((course=>course.tasks)).flatMap((task=>task.headline)).map((headline=>headline.name)).concat(courseController.getSelectedCourse().name.map((n=>n.value))).includes(nameElem.value)})()||(nameElem.value=newHeadline),taskDisplayElement.value=newHeadline}function getLocalizedLinkFromTask(task){return task.link+"?lang="+langController.getSelectedLanguage()}return{init:function(){updateName()},getSelectedTask:function(){const selectedLink=taskSelectionInput.value,selectedCourse=courseController.getSelectedCourse();if(!selectedCourse)return null;const tasks=selectedCourse.tasks.slice();return tasks.push(function(course){var headline=[];for(var i in course.name){var name=course.name[i];headline.push({name:name.value,language:name.language})}return{link:course.link,headline:headline}}(selectedCourse)),tasks.find((task=>getLocalizedLinkFromTask(task)===selectedLink))},setSelection:function(newSelection){taskSelectionInput.value=newSelection,updateName()},setIsGraded:function(isGraded){null===isGraded&&(isGradedElem.value=null),isGradedElem.value=isGraded?"1":"0",function(){const disabled="0"===isGradedElem.value;document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_duedate_enabled").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled}()},getGradingType:function(){const isGraded=isGradedElem.value;return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"}}}(),multiTaskEditController=function(){const propertySelectionInputs=document.getElementsByName("mumie_multi_edit_property"),selectedTaskProperties=document.getElementsByName("mumie_selected_task_properties")[0];let selectedTaskProp=[];const taskSelectionInputs=document.getElementsByName("mumie_multi_edit_task"),selectedTasks=document.getElementsByName("mumie_selected_tasks")[0];let selectedTaskIds=[];const sectionInputs=document.getElementsByName("mumie_multi_edit_section");return{init:function(){taskSelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskIds.push(checkbox.value):selectedTaskIds=selectedTaskIds.filter((elem=>elem!==checkbox.value)),selectedTasks.value=JSON.stringify(selectedTaskIds)}})),propertySelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskProp.push(checkbox.value):selectedTaskProp=selectedTaskProp.filter((elem=>elem!==checkbox.value)),selectedTaskProperties.value=JSON.stringify(selectedTaskProp)}})),sectionInputs.forEach((function(sectionCheckbox){sectionCheckbox.onchange=function(){sectionCheckbox.checked?taskSelectionInputs.forEach((function(taskCheckbox){var array,element;taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!0,array=selectedTaskIds,element=taskCheckbox.value,array.includes(element)||array.push(element))})):taskSelectionInputs.forEach((function(taskCheckbox){taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!1,selectedTaskIds=selectedTaskIds.filter((elem=>taskCheckbox.value!==elem)))})),selectedTasks.value=JSON.stringify(selectedTaskIds)}}))}}}();function disableDropDownMenus(errorKey){require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:errorKey,component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0]+""+missingConfig.getAttribute("value")+"",type:"problem"})})).fail(notification.exception)})),serverController.disable(),problemSelectorController.disable()}return{init:function(contextid,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang;const isEdit=document.getElementById("id_name").getAttribute("value"),serverStructure=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);isEdit&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?disableDropDownMenus("mumie_form_missing_server"):serverStructure.length?(serverController.init(serverStructure),courseController.init(),taskController.init(isEdit),multiTaskEditController.init(),problemSelectorController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextid)}))}}})); +define("mod_mumie/mod_form",["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],(function(){var lmsSelectorUrl,systemLanguage,serverStructure,serverDropDown,languageElem,propertySelectionInputs,selectedTaskProperties,selectedTaskProp,taskSelectionInputs,selectedTasks,selectedTaskIds,sectionInputs,addServerButton=document.getElementById("id_add_server_button"),missingConfig=document.getElementsByName("mumie_missing_config")[0],serverController=(serverDropDown=document.getElementById("id_server"),{init:function(structure){serverStructure=structure},getSelectedServer:function(){var selectedServerName=serverDropDown.options[serverDropDown.selectedIndex].text;return serverStructure.find((function(server){return server.name===selectedServerName}))},disable:function(){serverDropDown.disabled=!0,function(elem){for(;elem.firstChild;)elem.removeChild(elem.firstChild)}(serverDropDown)},getAllServers:function(){return serverStructure}}),problemSelectorController=function(){var problemSelectorWindow,problemSelectorButton=document.getElementById("id_prb_selector_btn"),multiProblemSelectorButton=document.getElementById("id_multi_problem_selector_btn"),mumieOrg=document.getElementsByName("mumie_org")[0].value;function sendResponse(response){problemSelectorWindow&&problemSelectorWindow.postMessage(JSON.stringify(response),lmsSelectorUrl)}function sendSuccess(){var message=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";sendResponse({success:!0,message:message})}function addMessageListener(){window.addEventListener("message",(function(event){if(event.origin===lmsSelectorUrl){var importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link+"?lang="+importObj.language),taskController.setIsGraded(isGraded),sendSuccess(),window.focus(),require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0],type:"info"})})).fail(notification.exception)}))}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}}),!1)}return{init:function(){var gradingType=taskController.getGradingType();problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true","_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}(),courseController=function(){var courseNameElem=document.getElementById("id_mumie_course"),coursefileElem=document.getElementsByName("mumie_coursefile")[0];function _updateCourseName(){var _selectedCourse$name$,selectedCourse=courseController.getSelectedCourse(),selectedLanguage=langController.getSelectedLanguage();selectedCourse&&selectedLanguage&&(courseNameElem.value=null===(_selectedCourse$name$=selectedCourse.name.find((function(translation){return translation.language===selectedLanguage})))||void 0===_selectedCourse$name$?void 0:_selectedCourse$name$.value)}return{init:function(){_updateCourseName()},getSelectedCourse:function(){return serverController.getSelectedServer().courses.find((function(course){return course.coursefile===coursefileElem.value}))},updateCourseName:function(){_updateCourseName()},setCourse:function(courseFile){var coursefile;coursefile=courseFile,coursefileElem.value=coursefile,_updateCourseName()}}}(),langController=(languageElem=document.getElementById("id_language"),{getSelectedLanguage:function(){return languageElem.value},setLanguage:function(lang){if(!function(lang){return courseController.getSelectedCourse().languages.includes(lang)}(lang))throw new Error("Selected language not available");languageElem.value=lang,courseController.updateCourseName()}}),taskController=function(){var taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element"),isGradedElem=document.getElementById("id_mumie_isgraded");function updateName(){var newHeadline=function(task){if(!task)return null;var selectedLanguage=langController.getSelectedLanguage(),headlineWrapper=task.headline.find((function(localHeadline){return localHeadline.language===selectedLanguage}));return headlineWrapper?headlineWrapper.name:null}(taskController.getSelectedTask());(function(){if(0===nameElem.value.length)return!1;return!serverController.getAllServers().flatMap((function(server){return server.courses})).flatMap((function(course){return course.tasks})).flatMap((function(task){return task.headline})).map((function(headline){return headline.name})).concat(courseController.getSelectedCourse().name.map((function(n){return n.value}))).includes(nameElem.value)})()||(nameElem.value=newHeadline),taskDisplayElement.value=newHeadline}function getLocalizedLinkFromTask(task){return task.link+"?lang="+langController.getSelectedLanguage()}return{init:function(){updateName()},getSelectedTask:function(){var selectedLink=taskSelectionInput.value,selectedCourse=courseController.getSelectedCourse();if(!selectedCourse)return null;var tasks=selectedCourse.tasks.slice();return tasks.push(function(course){var headline=[];for(var i in course.name){var name=course.name[i];headline.push({name:name.value,language:name.language})}return{link:course.link,headline:headline}}(selectedCourse)),tasks.find((function(task){return getLocalizedLinkFromTask(task)===selectedLink}))},setSelection:function(newSelection){taskSelectionInput.value=newSelection,updateName()},setIsGraded:function(isGraded){var disabled;null===isGraded&&(isGradedElem.value=null),isGradedElem.value=isGraded?"1":"0",disabled="0"===isGradedElem.value,document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_duedate_enabled").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled},getGradingType:function(){var isGraded=isGradedElem.value;return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"}}}(),multiTaskEditController=(propertySelectionInputs=document.getElementsByName("mumie_multi_edit_property"),selectedTaskProperties=document.getElementsByName("mumie_selected_task_properties")[0],selectedTaskProp=[],taskSelectionInputs=document.getElementsByName("mumie_multi_edit_task"),selectedTasks=document.getElementsByName("mumie_selected_tasks")[0],selectedTaskIds=[],sectionInputs=document.getElementsByName("mumie_multi_edit_section"),{init:function(){taskSelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskIds.push(checkbox.value):selectedTaskIds=selectedTaskIds.filter((function(elem){return elem!==checkbox.value})),selectedTasks.value=JSON.stringify(selectedTaskIds)}})),propertySelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskProp.push(checkbox.value):selectedTaskProp=selectedTaskProp.filter((function(elem){return elem!==checkbox.value})),selectedTaskProperties.value=JSON.stringify(selectedTaskProp)}})),sectionInputs.forEach((function(sectionCheckbox){sectionCheckbox.onchange=function(){sectionCheckbox.checked?taskSelectionInputs.forEach((function(taskCheckbox){var array,element;taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!0,array=selectedTaskIds,element=taskCheckbox.value,array.includes(element)||array.push(element))})):taskSelectionInputs.forEach((function(taskCheckbox){taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!1,selectedTaskIds=selectedTaskIds.filter((function(elem){return taskCheckbox.value!==elem})))})),selectedTasks.value=JSON.stringify(selectedTaskIds)}}))}});function disableDropDownMenus(errorKey){require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:errorKey,component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0]+""+missingConfig.getAttribute("value")+"",type:"problem"})})).fail(notification.exception)})),serverController.disable(),problemSelectorController.disable()}return{init:function(contextid,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang;var isEdit=document.getElementById("id_name").getAttribute("value"),serverStructure=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);isEdit&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?disableDropDownMenus("mumie_form_missing_server"):serverStructure.length?(serverController.init(serverStructure),courseController.init(),taskController.init(isEdit),multiTaskEditController.init(),problemSelectorController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextid)}))}}})); //# sourceMappingURL=mod_form.min.js.map \ No newline at end of file diff --git a/amd/build/mod_form.min.js.map b/amd/build/mod_form.min.js.map index ca3ed7c..853486f 100644 --- a/amd/build/mod_form.min.js.map +++ b/amd/build/mod_form.min.js.map @@ -1 +1 @@ -{"version":3,"file":"mod_form.min.js","sources":["../src/mod_form.js"],"sourcesContent":["define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_server_config', 'core/ajax'],\n function() {\n const addServerButton = document.getElementById(\"id_add_server_button\");\n const missingConfig = document.getElementsByName(\"mumie_missing_config\")[0];\n let lmsSelectorUrl;\n let systemLanguage;\n const serverController = (function() {\n let serverStructure;\n const serverDropDown = document.getElementById(\"id_server\");\n\n return {\n init: function(structure) {\n serverStructure = structure;\n },\n getSelectedServer: function() {\n const selectedServerName = serverDropDown.options[serverDropDown.selectedIndex].text;\n return serverStructure.find(server => server.name === selectedServerName);\n },\n disable: function() {\n serverDropDown.disabled = true;\n removeChildElems(serverDropDown);\n },\n getAllServers: function() {\n return serverStructure;\n }\n };\n })();\n\n const problemSelectorController = (function() {\n const problemSelectorButton = document.getElementById('id_prb_selector_btn');\n const multiProblemSelectorButton = document.getElementById('id_multi_problem_selector_btn');\n let problemSelectorWindow;\n const mumieOrg = document.getElementsByName('mumie_org')[0].value;\n\n /**\n * Send a message to the problem selector window.\n *\n * Don't do anything, if there is no problem selector window.\n * @param {Object} response\n */\n function sendResponse(response) {\n if (!problemSelectorWindow) {\n return;\n }\n problemSelectorWindow.postMessage(JSON.stringify(response), lmsSelectorUrl);\n }\n\n /**\n * Send a success message to problem selector window\n * @param {string} message\n */\n function sendSuccess(message = '') {\n sendResponse({\n success: true,\n message: message\n });\n }\n\n /**\n * Send a failure message to problem selector window\n * @param {string} message\n */\n function sendFailure(message = '') {\n sendResponse({\n success: false,\n message: message\n });\n }\n\n /**\n * Add an event listener that accepts messages from LMS-Browser and updates the selected problem.\n */\n function addMessageListener() {\n window.addEventListener('message', (event) => {\n if (event.origin !== lmsSelectorUrl) {\n return;\n }\n const importObj = JSON.parse(event.data);\n const isGraded = importObj.isGraded !== false;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link + '?lang=' + importObj.language);\n taskController.setIsGraded(isGraded);\n sendSuccess();\n window.focus();\n displayProblemSelectedMessage();\n } catch (error) {\n sendFailure(error.message);\n }\n }, false);\n }\n\n /**\n * Display a success message in Moodle that a problem was successfully selected.\n */\n function displayProblemSelectedMessage() {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': 'mumie_form_updated_selection',\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0],\n type: \"info\"\n });\n }).fail(notification.exception);\n });\n }\n\n return {\n init: function() {\n const gradingType = taskController.getGradingType();\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + 'org='\n + mumieOrg\n + '&serverUrl='\n + encodeURIComponent(serverController.getSelectedServer().urlprefix)\n + '&problemLang='\n + langController.getSelectedLanguage()\n + '&origin=' + encodeURIComponent(window.location.origin)\n + '&uiLang=' + systemLanguage\n + '&gradingType=' + gradingType\n + '&multiCourse=true'\n , '_blank'\n );\n };\n\n window.onclose = function() {\n sendSuccess();\n };\n\n window.addEventListener(\"beforeunload\", function() {\n sendSuccess();\n }, false);\n\n addMessageListener();\n\n multiProblemSelectorButton.onclick = function(e) {\n e.preventDefault();\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + \"serverUrl=\"\n + encodeURIComponent(serverController.getSelectedServer().urlprefix),\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n }\n };\n })();\n\n const courseController = (function() {\n const courseNameElem = document.getElementById(\"id_mumie_course\");\n const coursefileElem = document.getElementsByName(\"mumie_coursefile\")[0];\n\n\n /**\n * Update the hidden input field with the selected course's course file path\n *\n * @param {string} coursefile\n */\n function updateCoursefilePath(coursefile) {\n coursefileElem.value = coursefile;\n updateCourseName();\n }\n\n /**\n * Update displayed course name.\n */\n function updateCourseName() {\n const selectedCourse = courseController.getSelectedCourse();\n const selectedLanguage = langController.getSelectedLanguage();\n if (!selectedCourse || !selectedLanguage) {\n return;\n }\n courseNameElem.value = selectedCourse.name\n .find(translation => translation.language === selectedLanguage)?.value;\n }\n\n return {\n init: function() {\n updateCourseName();\n },\n getSelectedCourse: function() {\n const courses = serverController.getSelectedServer().courses;\n return courses.find(course => course.coursefile === coursefileElem.value);\n },\n updateCourseName: function() {\n updateCourseName();\n },\n setCourse: function(courseFile) {\n updateCoursefilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n\n /**\n * Check if the given language exists in the currently selected course.\n * @param {string} lang\n * @returns {boolean} Whether the language exists\n */\n function languageExists(lang) {\n return courseController.getSelectedCourse().languages.includes(lang);\n }\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n if (!languageExists(lang)) {\n throw new Error(\"Selected language not available\");\n }\n languageElem.value = lang;\n courseController.updateCourseName();\n }\n };\n })();\n\n const taskController = (function() {\n const taskSelectionInput = document.getElementsByName(\"taskurl\")[0];\n const nameElem = document.getElementById(\"id_name\");\n const taskDisplayElement = document.getElementById(\"id_task_display_element\");\n const isGradedElem = document.getElementById('id_mumie_isgraded');\n\n\n /**\n * Update the activity's name in the input field\n */\n function updateName() {\n const newHeadline = getHeadline(taskController.getSelectedTask());\n if (!isCustomName()) {\n nameElem.value = newHeadline;\n }\n taskDisplayElement.value = newHeadline;\n }\n\n /**\n * Check whether the activity has a custom name\n *\n * @return {boolean} True, if there is no headline with that name in all tasks\n */\n function isCustomName() {\n if (nameElem.value.length === 0) {\n return false;\n }\n return !getAllHeadlines().includes(nameElem.value);\n }\n\n /**\n * Get the task's headline for the currently selected language\n * @param {Object} task\n * @returns {string|null} the headline\n */\n function getHeadline(task) {\n if (!task) {\n return null;\n }\n const selectedLanguage = langController.getSelectedLanguage();\n const headlineWrapper = task.headline.find(localHeadline => localHeadline.language === selectedLanguage);\n return headlineWrapper ? headlineWrapper.name : null;\n }\n\n /**\n * Get all tasks that are available on all servers\n *\n * @return {Object} Array containing all available tasks\n */\n function getAllTasks() {\n return serverController.getAllServers()\n .flatMap(server => server.courses)\n .flatMap(course => course.tasks);\n }\n\n /**\n * Get all possible headlines in all languages\n * @returns {Object} Array containing all headlines\n */\n function getAllHeadlines() {\n return getAllTasks().flatMap(task => task.headline)\n .map(headline => headline.name)\n .concat(courseController.getSelectedCourse().name.map(n => n.value));\n }\n\n /**\n * Add language parameter to the task's link to display content in the selected language\n * @param {Object} task\n * @returns {string}\n */\n function getLocalizedLinkFromTask(task) {\n return getLocalizedLink(task.link);\n }\n\n /**\n * Add language parameter to link\n * @param {string} link\n * @returns {string}\n */\n function getLocalizedLink(link) {\n return link + \"?lang=\" + langController.getSelectedLanguage();\n }\n\n /**\n * Form inputs related to grades should be disabled, if the MUMIE Task is not graded.\n */\n function updateGradeEditability() {\n const disabled = isGradedElem.value === '0';\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_duedate_enabled').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n }\n\n /**\n * Get a task that links to a course's overview page\n * @param {Object} course\n * @returns {Object} task\n */\n function getPseudoTaskFromCourse(course) {\n var headline = [];\n for (var i in course.name) {\n var name = course.name[i];\n headline.push({\n \"name\": name.value,\n \"language\": name.language\n });\n }\n return {\n \"link\": course.link,\n \"headline\": headline\n };\n }\n\n return {\n init: function() {\n updateName();\n },\n getSelectedTask: function() {\n const selectedLink = taskSelectionInput.value;\n const selectedCourse = courseController.getSelectedCourse();\n if (!selectedCourse) {\n return null;\n }\n const tasks = selectedCourse\n .tasks\n .slice();\n tasks.push(getPseudoTaskFromCourse(selectedCourse));\n return tasks\n .find(task => getLocalizedLinkFromTask(task) === selectedLink);\n },\n setSelection: function(newSelection) {\n taskSelectionInput.value = newSelection;\n updateName();\n },\n setIsGraded: function(isGraded) {\n if (isGraded === null) {\n isGradedElem.value = null;\n }\n isGradedElem.value = isGraded ? '1' : '0';\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = isGradedElem.value;\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n }\n };\n })();\n\n\n const multiTaskEditController = (function() {\n const propertySelectionInputs = document.getElementsByName(\"mumie_multi_edit_property\");\n const selectedTaskProperties = document.getElementsByName(\"mumie_selected_task_properties\")[0];\n let selectedTaskProp = [];\n const taskSelectionInputs = document.getElementsByName(\"mumie_multi_edit_task\");\n const selectedTasks = document.getElementsByName(\"mumie_selected_tasks\")[0];\n let selectedTaskIds = [];\n const sectionInputs = document.getElementsByName(\"mumie_multi_edit_section\");\n\n /**\n * Push an element to an array, if it's not already included.\n *\n * @param {string[]} array\n * @param {string} element\n */\n function pushIfNotExists(array, element) {\n if (!array.includes(element)) {\n array.push(element);\n }\n }\n\n /**\n * Set selection listeners for other MUMIE Tasks in the course.\n */\n function setTaskSelectionListeners() {\n taskSelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskIds = selectedTaskIds.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskIds.push(checkbox.value);\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n /**\n * Set selection listeners for properties to apply to MUMIE Tasks in the course.\n */\n function setPropertySelectionListeners() {\n propertySelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskProp = selectedTaskProp.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskProp.push(checkbox.value);\n }\n selectedTaskProperties.value = JSON.stringify(selectedTaskProp);\n };\n });\n }\n\n /**\n * Set selection listeners for entire section of MUMIE Tasks in the course\n */\n function setSectionSelectionListeners() {\n sectionInputs.forEach(function(sectionCheckbox) {\n sectionCheckbox.onchange = function() {\n if (!sectionCheckbox.checked) {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = false;\n selectedTaskIds = selectedTaskIds.filter(elem => taskCheckbox.value !== elem);\n }\n });\n } else {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = true;\n pushIfNotExists(selectedTaskIds, taskCheckbox.value);\n }\n });\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n return {\n init: function() {\n setTaskSelectionListeners();\n setPropertySelectionListeners();\n setSectionSelectionListeners();\n },\n };\n })();\n\n /**\n * Disable all dropdown menus and show notification\n * @param {string} errorKey\n */\n function disableDropDownMenus(errorKey) {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': errorKey,\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0] + \"\" + missingConfig.getAttribute(\"value\") + \"\",\n type: \"problem\"\n });\n }).fail(notification.exception);\n });\n serverController.disable();\n problemSelectorController.disable();\n }\n\n return {\n init: function(contextid, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n const isEdit = document.getElementById(\"id_name\").getAttribute('value');\n const serverStructure = JSON.parse(document.getElementsByName('mumie_server_structure')[0].value);\n if (isEdit && !serverConfigExists()) {\n disableDropDownMenus('mumie_form_missing_server');\n } else if (!serverStructure.length) {\n disableDropDownMenus('mumie_form_no_server_conf');\n } else {\n serverController.init(serverStructure);\n courseController.init();\n taskController.init(isEdit);\n multiTaskEditController.init();\n problemSelectorController.init();\n }\n multiTaskEditController.init();\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextid);\n });\n }\n }\n };\n\n /**\n * Remove all child elements of a given html element\n * @param {Object} elem\n */\n function removeChildElems(elem) {\n while (elem.firstChild) {\n elem.removeChild(elem.firstChild);\n }\n }\n\n /**\n * Check, if the flag for an existing config is set\n * @returns {boolean}\n */\n function serverConfigExists() {\n return document.getElementsByName(\"mumie_missing_config\")[0].getAttribute(\"value\") === \"\";\n }\n });\n"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","serverController","serverStructure","serverDropDown","init","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","getAllServers","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","value","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","window","addEventListener","event","origin","importObj","parse","data","isGraded","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","gradingType","getGradingType","onclick","open","encodeURIComponent","urlprefix","getSelectedLanguage","location","onclose","e","preventDefault","courseNameElem","coursefileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","languages","includes","languageExists","Error","taskSelectionInput","nameElem","taskDisplayElement","isGradedElem","updateName","newHeadline","task","headlineWrapper","headline","localHeadline","getHeadline","getSelectedTask","length","flatMap","tasks","map","concat","n","isCustomName","getLocalizedLinkFromTask","selectedLink","slice","push","i","getPseudoTaskFromCourse","newSelection","updateGradeEditability","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","onchange","checked","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","disableDropDownMenus","errorKey","contextid","prbSelectorUrl","isEdit","MumieServer"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"mod_form.min.js","sources":["../src/mod_form.js"],"sourcesContent":["define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_server_config', 'core/ajax'],\n function() {\n const addServerButton = document.getElementById(\"id_add_server_button\");\n const missingConfig = document.getElementsByName(\"mumie_missing_config\")[0];\n let lmsSelectorUrl;\n let systemLanguage;\n const serverController = (function() {\n let serverStructure;\n const serverDropDown = document.getElementById(\"id_server\");\n\n return {\n init: function(structure) {\n serverStructure = structure;\n },\n getSelectedServer: function() {\n const selectedServerName = serverDropDown.options[serverDropDown.selectedIndex].text;\n return serverStructure.find(server => server.name === selectedServerName);\n },\n disable: function() {\n serverDropDown.disabled = true;\n removeChildElems(serverDropDown);\n },\n getAllServers: function() {\n return serverStructure;\n }\n };\n })();\n\n const problemSelectorController = (function() {\n const problemSelectorButton = document.getElementById('id_prb_selector_btn');\n const multiProblemSelectorButton = document.getElementById('id_multi_problem_selector_btn');\n let problemSelectorWindow;\n const mumieOrg = document.getElementsByName('mumie_org')[0].value;\n\n /**\n * Send a message to the problem selector window.\n *\n * Don't do anything, if there is no problem selector window.\n * @param {Object} response\n */\n function sendResponse(response) {\n if (!problemSelectorWindow) {\n return;\n }\n problemSelectorWindow.postMessage(JSON.stringify(response), lmsSelectorUrl);\n }\n\n /**\n * Send a success message to problem selector window\n * @param {string} message\n */\n function sendSuccess(message = '') {\n sendResponse({\n success: true,\n message: message\n });\n }\n\n /**\n * Send a failure message to problem selector window\n * @param {string} message\n */\n function sendFailure(message = '') {\n sendResponse({\n success: false,\n message: message\n });\n }\n\n /**\n * Add an event listener that accepts messages from LMS-Browser and updates the selected problem.\n */\n function addMessageListener() {\n window.addEventListener('message', (event) => {\n if (event.origin !== lmsSelectorUrl) {\n return;\n }\n const importObj = JSON.parse(event.data);\n const isGraded = importObj.isGraded !== false;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link + '?lang=' + importObj.language);\n taskController.setIsGraded(isGraded);\n sendSuccess();\n window.focus();\n displayProblemSelectedMessage();\n } catch (error) {\n sendFailure(error.message);\n }\n }, false);\n }\n\n /**\n * Display a success message in Moodle that a problem was successfully selected.\n */\n function displayProblemSelectedMessage() {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': 'mumie_form_updated_selection',\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0],\n type: \"info\"\n });\n }).fail(notification.exception);\n });\n }\n\n return {\n init: function() {\n const gradingType = taskController.getGradingType();\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + 'org='\n + mumieOrg\n + '&serverUrl='\n + encodeURIComponent(serverController.getSelectedServer().urlprefix)\n + '&problemLang='\n + langController.getSelectedLanguage()\n + '&origin=' + encodeURIComponent(window.location.origin)\n + '&uiLang=' + systemLanguage\n + '&gradingType=' + gradingType\n + '&multiCourse=true'\n , '_blank'\n );\n };\n\n window.onclose = function() {\n sendSuccess();\n };\n\n window.addEventListener(\"beforeunload\", function() {\n sendSuccess();\n }, false);\n\n addMessageListener();\n\n multiProblemSelectorButton.onclick = function(e) {\n e.preventDefault();\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + \"serverUrl=\"\n + encodeURIComponent(serverController.getSelectedServer().urlprefix),\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n }\n };\n })();\n\n const courseController = (function() {\n const courseNameElem = document.getElementById(\"id_mumie_course\");\n const coursefileElem = document.getElementsByName(\"mumie_coursefile\")[0];\n\n\n /**\n * Update the hidden input field with the selected course's course file path\n *\n * @param {string} coursefile\n */\n function updateCoursefilePath(coursefile) {\n coursefileElem.value = coursefile;\n updateCourseName();\n }\n\n /**\n * Update displayed course name.\n */\n function updateCourseName() {\n const selectedCourse = courseController.getSelectedCourse();\n const selectedLanguage = langController.getSelectedLanguage();\n if (!selectedCourse || !selectedLanguage) {\n return;\n }\n courseNameElem.value = selectedCourse.name\n .find(translation => translation.language === selectedLanguage)?.value;\n }\n\n return {\n init: function() {\n updateCourseName();\n },\n getSelectedCourse: function() {\n const courses = serverController.getSelectedServer().courses;\n return courses.find(course => course.coursefile === coursefileElem.value);\n },\n updateCourseName: function() {\n updateCourseName();\n },\n setCourse: function(courseFile) {\n updateCoursefilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n\n /**\n * Check if the given language exists in the currently selected course.\n * @param {string} lang\n * @returns {boolean} Whether the language exists\n */\n function languageExists(lang) {\n return courseController.getSelectedCourse().languages.includes(lang);\n }\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n if (!languageExists(lang)) {\n throw new Error(\"Selected language not available\");\n }\n languageElem.value = lang;\n courseController.updateCourseName();\n }\n };\n })();\n\n const taskController = (function() {\n const taskSelectionInput = document.getElementsByName(\"taskurl\")[0];\n const nameElem = document.getElementById(\"id_name\");\n const taskDisplayElement = document.getElementById(\"id_task_display_element\");\n const isGradedElem = document.getElementById('id_mumie_isgraded');\n\n\n /**\n * Update the activity's name in the input field\n */\n function updateName() {\n const newHeadline = getHeadline(taskController.getSelectedTask());\n if (!isCustomName()) {\n nameElem.value = newHeadline;\n }\n taskDisplayElement.value = newHeadline;\n }\n\n /**\n * Check whether the activity has a custom name\n *\n * @return {boolean} True, if there is no headline with that name in all tasks\n */\n function isCustomName() {\n if (nameElem.value.length === 0) {\n return false;\n }\n return !getAllHeadlines().includes(nameElem.value);\n }\n\n /**\n * Get the task's headline for the currently selected language\n * @param {Object} task\n * @returns {string|null} the headline\n */\n function getHeadline(task) {\n if (!task) {\n return null;\n }\n const selectedLanguage = langController.getSelectedLanguage();\n const headlineWrapper = task.headline.find(localHeadline => localHeadline.language === selectedLanguage);\n return headlineWrapper ? headlineWrapper.name : null;\n }\n\n /**\n * Get all tasks that are available on all servers\n *\n * @return {Object} Array containing all available tasks\n */\n function getAllTasks() {\n return serverController.getAllServers()\n .flatMap(server => server.courses)\n .flatMap(course => course.tasks);\n }\n\n /**\n * Get all possible headlines in all languages\n * @returns {Object} Array containing all headlines\n */\n function getAllHeadlines() {\n return getAllTasks().flatMap(task => task.headline)\n .map(headline => headline.name)\n .concat(courseController.getSelectedCourse().name.map(n => n.value));\n }\n\n /**\n * Add language parameter to the task's link to display content in the selected language\n * @param {Object} task\n * @returns {string}\n */\n function getLocalizedLinkFromTask(task) {\n return getLocalizedLink(task.link);\n }\n\n /**\n * Add language parameter to link\n * @param {string} link\n * @returns {string}\n */\n function getLocalizedLink(link) {\n return link + \"?lang=\" + langController.getSelectedLanguage();\n }\n\n /**\n * Form inputs related to grades should be disabled, if the MUMIE Task is not graded.\n */\n function updateGradeEditability() {\n const disabled = isGradedElem.value === '0';\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_duedate_enabled').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n }\n\n /**\n * Get a task that links to a course's overview page\n * @param {Object} course\n * @returns {Object} task\n */\n function getPseudoTaskFromCourse(course) {\n var headline = [];\n for (var i in course.name) {\n var name = course.name[i];\n headline.push({\n \"name\": name.value,\n \"language\": name.language\n });\n }\n return {\n \"link\": course.link,\n \"headline\": headline\n };\n }\n\n return {\n init: function() {\n updateName();\n },\n getSelectedTask: function() {\n const selectedLink = taskSelectionInput.value;\n const selectedCourse = courseController.getSelectedCourse();\n if (!selectedCourse) {\n return null;\n }\n const tasks = selectedCourse\n .tasks\n .slice();\n tasks.push(getPseudoTaskFromCourse(selectedCourse));\n return tasks\n .find(task => getLocalizedLinkFromTask(task) === selectedLink);\n },\n setSelection: function(newSelection) {\n taskSelectionInput.value = newSelection;\n updateName();\n },\n setIsGraded: function(isGraded) {\n if (isGraded === null) {\n isGradedElem.value = null;\n }\n isGradedElem.value = isGraded ? '1' : '0';\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = isGradedElem.value;\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n }\n };\n })();\n\n\n const multiTaskEditController = (function() {\n const propertySelectionInputs = document.getElementsByName(\"mumie_multi_edit_property\");\n const selectedTaskProperties = document.getElementsByName(\"mumie_selected_task_properties\")[0];\n let selectedTaskProp = [];\n const taskSelectionInputs = document.getElementsByName(\"mumie_multi_edit_task\");\n const selectedTasks = document.getElementsByName(\"mumie_selected_tasks\")[0];\n let selectedTaskIds = [];\n const sectionInputs = document.getElementsByName(\"mumie_multi_edit_section\");\n\n /**\n * Push an element to an array, if it's not already included.\n *\n * @param {string[]} array\n * @param {string} element\n */\n function pushIfNotExists(array, element) {\n if (!array.includes(element)) {\n array.push(element);\n }\n }\n\n /**\n * Set selection listeners for other MUMIE Tasks in the course.\n */\n function setTaskSelectionListeners() {\n taskSelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskIds = selectedTaskIds.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskIds.push(checkbox.value);\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n /**\n * Set selection listeners for properties to apply to MUMIE Tasks in the course.\n */\n function setPropertySelectionListeners() {\n propertySelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskProp = selectedTaskProp.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskProp.push(checkbox.value);\n }\n selectedTaskProperties.value = JSON.stringify(selectedTaskProp);\n };\n });\n }\n\n /**\n * Set selection listeners for entire section of MUMIE Tasks in the course\n */\n function setSectionSelectionListeners() {\n sectionInputs.forEach(function(sectionCheckbox) {\n sectionCheckbox.onchange = function() {\n if (!sectionCheckbox.checked) {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = false;\n selectedTaskIds = selectedTaskIds.filter(elem => taskCheckbox.value !== elem);\n }\n });\n } else {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = true;\n pushIfNotExists(selectedTaskIds, taskCheckbox.value);\n }\n });\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n return {\n init: function() {\n setTaskSelectionListeners();\n setPropertySelectionListeners();\n setSectionSelectionListeners();\n },\n };\n })();\n\n /**\n * Disable all dropdown menus and show notification\n * @param {string} errorKey\n */\n function disableDropDownMenus(errorKey) {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': errorKey,\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0] + \"\" + missingConfig.getAttribute(\"value\") + \"\",\n type: \"problem\"\n });\n }).fail(notification.exception);\n });\n serverController.disable();\n problemSelectorController.disable();\n }\n\n return {\n init: function(contextid, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n const isEdit = document.getElementById(\"id_name\").getAttribute('value');\n const serverStructure = JSON.parse(document.getElementsByName('mumie_server_structure')[0].value);\n if (isEdit && !serverConfigExists()) {\n disableDropDownMenus('mumie_form_missing_server');\n } else if (!serverStructure.length) {\n disableDropDownMenus('mumie_form_no_server_conf');\n } else {\n serverController.init(serverStructure);\n courseController.init();\n taskController.init(isEdit);\n multiTaskEditController.init();\n problemSelectorController.init();\n }\n multiTaskEditController.init();\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextid);\n });\n }\n }\n };\n\n /**\n * Remove all child elements of a given html element\n * @param {Object} elem\n */\n function removeChildElems(elem) {\n while (elem.firstChild) {\n elem.removeChild(elem.firstChild);\n }\n }\n\n /**\n * Check, if the flag for an existing config is set\n * @returns {boolean}\n */\n function serverConfigExists() {\n return document.getElementsByName(\"mumie_missing_config\")[0].getAttribute(\"value\") === \"\";\n }\n });\n"],"names":["define","lmsSelectorUrl","systemLanguage","serverStructure","serverDropDown","languageElem","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","addServerButton","document","getElementById","missingConfig","getElementsByName","serverController","init","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","getAllServers","problemSelectorController","problemSelectorWindow","problemSelectorButton","multiProblemSelectorButton","mumieOrg","value","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","window","addEventListener","event","origin","importObj","parse","data","isGraded","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","gradingType","getGradingType","onclick","open","encodeURIComponent","urlprefix","getSelectedLanguage","location","onclose","e","preventDefault","courseNameElem","coursefileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","lang","languages","includes","languageExists","Error","taskSelectionInput","nameElem","taskDisplayElement","isGradedElem","updateName","newHeadline","task","headlineWrapper","headline","localHeadline","getHeadline","getSelectedTask","length","flatMap","tasks","map","concat","n","isCustomName","getLocalizedLinkFromTask","selectedLink","slice","push","i","getPseudoTaskFromCourse","newSelection","multiTaskEditController","forEach","checkbox","onchange","checked","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","disableDropDownMenus","errorKey","contextid","prbSelectorUrl","isEdit","MumieServer"],"mappings":"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"} \ No newline at end of file From 6d042b8cf154e0650a586c97058e5ce13dde2e46 Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 23 Feb 2023 17:21:20 +0100 Subject: [PATCH 06/10] Fixing codestyle violations --- classes/mumie_calendar_service/mumie_calendar_service.php | 2 +- mod_form.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/mumie_calendar_service/mumie_calendar_service.php b/classes/mumie_calendar_service/mumie_calendar_service.php index fbd1b28..3a80aa7 100644 --- a/classes/mumie_calendar_service/mumie_calendar_service.php +++ b/classes/mumie_calendar_service/mumie_calendar_service.php @@ -98,7 +98,7 @@ public function update() { $this->mumie->duedate ); } else if ($this->event && $hasduedate) { - $update = new \stdClass(); + $update = new \stdClass(); $update->name = $this->title; $update->timestart = $this->mumie->duedate; $this->event->update($update, false); diff --git a/mod_form.php b/mod_form.php index 997fc64..afc14b0 100644 --- a/mod_form.php +++ b/mod_form.php @@ -109,12 +109,12 @@ public function definition() { $mform->setType("task_display_element", PARAM_TEXT); $contentbutton = $mform->addElement('button', 'prb_selector_btn', get_string('mumie_form_prb_selector_btn', 'mod_mumie')); - $wiki_link = 'https://wiki.mumie.net/wiki/MUMIE-Moodle-integration-for-teachers#how-to-create-mumie-tasks-with-drag-and-drop'; + $wiki = 'https://wiki.mumie.net/wiki/MUMIE-Moodle-integration-for-teachers#how-to-create-mumie-tasks-with-drag-and-drop'; $this->add_info_box( get_string( "mumie_multi_problem_selector", "mod_mumie", - $wiki_link)); + $wiki)); $mform->addElement('button', 'multi_problem_selector_btn', get_string('mumie_form_multi_prb_selector_btn', 'mod_mumie')); $launchoptions = array(); From 5ad46ff9de46dc2327267f934cf6304988f00dc6 Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 23 Feb 2023 17:27:02 +0100 Subject: [PATCH 07/10] Fixing stale minified files --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 29f38fa..9e7bba6 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1,3 +1,3 @@ -define("mod_mumie/mod_form",["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],(function(){var lmsSelectorUrl,systemLanguage,serverStructure,serverDropDown,languageElem,propertySelectionInputs,selectedTaskProperties,selectedTaskProp,taskSelectionInputs,selectedTasks,selectedTaskIds,sectionInputs,addServerButton=document.getElementById("id_add_server_button"),missingConfig=document.getElementsByName("mumie_missing_config")[0],serverController=(serverDropDown=document.getElementById("id_server"),{init:function(structure){serverStructure=structure},getSelectedServer:function(){var selectedServerName=serverDropDown.options[serverDropDown.selectedIndex].text;return serverStructure.find((function(server){return server.name===selectedServerName}))},disable:function(){serverDropDown.disabled=!0,function(elem){for(;elem.firstChild;)elem.removeChild(elem.firstChild)}(serverDropDown)},getAllServers:function(){return serverStructure}}),problemSelectorController=function(){var problemSelectorWindow,problemSelectorButton=document.getElementById("id_prb_selector_btn"),multiProblemSelectorButton=document.getElementById("id_multi_problem_selector_btn"),mumieOrg=document.getElementsByName("mumie_org")[0].value;function sendResponse(response){problemSelectorWindow&&problemSelectorWindow.postMessage(JSON.stringify(response),lmsSelectorUrl)}function sendSuccess(){var message=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";sendResponse({success:!0,message:message})}function addMessageListener(){window.addEventListener("message",(function(event){if(event.origin===lmsSelectorUrl){var importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link+"?lang="+importObj.language),taskController.setIsGraded(isGraded),sendSuccess(),window.focus(),require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0],type:"info"})})).fail(notification.exception)}))}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}}),!1)}return{init:function(){var gradingType=taskController.getGradingType();problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true","_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}(),courseController=function(){var courseNameElem=document.getElementById("id_mumie_course"),coursefileElem=document.getElementsByName("mumie_coursefile")[0];function _updateCourseName(){var _selectedCourse$name$,selectedCourse=courseController.getSelectedCourse(),selectedLanguage=langController.getSelectedLanguage();selectedCourse&&selectedLanguage&&(courseNameElem.value=null===(_selectedCourse$name$=selectedCourse.name.find((function(translation){return translation.language===selectedLanguage})))||void 0===_selectedCourse$name$?void 0:_selectedCourse$name$.value)}return{init:function(){_updateCourseName()},getSelectedCourse:function(){return serverController.getSelectedServer().courses.find((function(course){return course.coursefile===coursefileElem.value}))},updateCourseName:function(){_updateCourseName()},setCourse:function(courseFile){var coursefile;coursefile=courseFile,coursefileElem.value=coursefile,_updateCourseName()}}}(),langController=(languageElem=document.getElementById("id_language"),{getSelectedLanguage:function(){return languageElem.value},setLanguage:function(lang){if(!function(lang){return courseController.getSelectedCourse().languages.includes(lang)}(lang))throw new Error("Selected language not available");languageElem.value=lang,courseController.updateCourseName()}}),taskController=function(){var taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element"),isGradedElem=document.getElementById("id_mumie_isgraded");function updateName(){var newHeadline=function(task){if(!task)return null;var selectedLanguage=langController.getSelectedLanguage(),headlineWrapper=task.headline.find((function(localHeadline){return localHeadline.language===selectedLanguage}));return headlineWrapper?headlineWrapper.name:null}(taskController.getSelectedTask());(function(){if(0===nameElem.value.length)return!1;return!serverController.getAllServers().flatMap((function(server){return server.courses})).flatMap((function(course){return course.tasks})).flatMap((function(task){return task.headline})).map((function(headline){return headline.name})).concat(courseController.getSelectedCourse().name.map((function(n){return n.value}))).includes(nameElem.value)})()||(nameElem.value=newHeadline),taskDisplayElement.value=newHeadline}function getLocalizedLinkFromTask(task){return task.link+"?lang="+langController.getSelectedLanguage()}return{init:function(){updateName()},getSelectedTask:function(){var selectedLink=taskSelectionInput.value,selectedCourse=courseController.getSelectedCourse();if(!selectedCourse)return null;var tasks=selectedCourse.tasks.slice();return tasks.push(function(course){var headline=[];for(var i in course.name){var name=course.name[i];headline.push({name:name.value,language:name.language})}return{link:course.link,headline:headline}}(selectedCourse)),tasks.find((function(task){return getLocalizedLinkFromTask(task)===selectedLink}))},setSelection:function(newSelection){taskSelectionInput.value=newSelection,updateName()},setIsGraded:function(isGraded){var disabled;null===isGraded&&(isGradedElem.value=null),isGradedElem.value=isGraded?"1":"0",disabled="0"===isGradedElem.value,document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_duedate_enabled").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled},getGradingType:function(){var isGraded=isGradedElem.value;return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"}}}(),multiTaskEditController=(propertySelectionInputs=document.getElementsByName("mumie_multi_edit_property"),selectedTaskProperties=document.getElementsByName("mumie_selected_task_properties")[0],selectedTaskProp=[],taskSelectionInputs=document.getElementsByName("mumie_multi_edit_task"),selectedTasks=document.getElementsByName("mumie_selected_tasks")[0],selectedTaskIds=[],sectionInputs=document.getElementsByName("mumie_multi_edit_section"),{init:function(){taskSelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskIds.push(checkbox.value):selectedTaskIds=selectedTaskIds.filter((function(elem){return elem!==checkbox.value})),selectedTasks.value=JSON.stringify(selectedTaskIds)}})),propertySelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskProp.push(checkbox.value):selectedTaskProp=selectedTaskProp.filter((function(elem){return elem!==checkbox.value})),selectedTaskProperties.value=JSON.stringify(selectedTaskProp)}})),sectionInputs.forEach((function(sectionCheckbox){sectionCheckbox.onchange=function(){sectionCheckbox.checked?taskSelectionInputs.forEach((function(taskCheckbox){var array,element;taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!0,array=selectedTaskIds,element=taskCheckbox.value,array.includes(element)||array.push(element))})):taskSelectionInputs.forEach((function(taskCheckbox){taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!1,selectedTaskIds=selectedTaskIds.filter((function(elem){return taskCheckbox.value!==elem})))})),selectedTasks.value=JSON.stringify(selectedTaskIds)}}))}});function disableDropDownMenus(errorKey){require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:errorKey,component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0]+""+missingConfig.getAttribute("value")+"",type:"problem"})})).fail(notification.exception)})),serverController.disable(),problemSelectorController.disable()}return{init:function(contextid,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang;var isEdit=document.getElementById("id_name").getAttribute("value"),serverStructure=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);isEdit&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?disableDropDownMenus("mumie_form_missing_server"):serverStructure.length?(serverController.init(serverStructure),courseController.init(),taskController.init(isEdit),multiTaskEditController.init(),problemSelectorController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextid)}))}}})); +define("mod_mumie/mod_form",["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],(function(){const addServerButton=document.getElementById("id_add_server_button"),missingConfig=document.getElementsByName("mumie_missing_config")[0];let lmsSelectorUrl,systemLanguage;const serverController=function(){let serverStructure;const serverDropDown=document.getElementById("id_server");return{init:function(structure){serverStructure=structure},getSelectedServer:function(){const selectedServerName=serverDropDown.options[serverDropDown.selectedIndex].text;return serverStructure.find((server=>server.name===selectedServerName))},disable:function(){serverDropDown.disabled=!0,function(elem){for(;elem.firstChild;)elem.removeChild(elem.firstChild)}(serverDropDown)},getAllServers:function(){return serverStructure}}}(),problemSelectorController=function(){const problemSelectorButton=document.getElementById("id_prb_selector_btn"),multiProblemSelectorButton=document.getElementById("id_multi_problem_selector_btn");let problemSelectorWindow;const mumieOrg=document.getElementsByName("mumie_org")[0].value;function sendResponse(response){problemSelectorWindow&&problemSelectorWindow.postMessage(JSON.stringify(response),lmsSelectorUrl)}function sendSuccess(){let message=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";sendResponse({success:!0,message:message})}function addMessageListener(){window.addEventListener("message",(event=>{if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link+"?lang="+importObj.language),taskController.setIsGraded(isGraded),sendSuccess(),window.focus(),require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0],type:"info"})})).fail(notification.exception)}))}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}return{init:function(){const gradingType=taskController.getGradingType();problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true","_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}(),courseController=function(){const courseNameElem=document.getElementById("id_mumie_course"),coursefileElem=document.getElementsByName("mumie_coursefile")[0];function updateCourseName(){var _selectedCourse$name$;const selectedCourse=courseController.getSelectedCourse(),selectedLanguage=langController.getSelectedLanguage();selectedCourse&&selectedLanguage&&(courseNameElem.value=null===(_selectedCourse$name$=selectedCourse.name.find((translation=>translation.language===selectedLanguage)))||void 0===_selectedCourse$name$?void 0:_selectedCourse$name$.value)}return{init:function(){updateCourseName()},getSelectedCourse:function(){return serverController.getSelectedServer().courses.find((course=>course.coursefile===coursefileElem.value))},updateCourseName:function(){updateCourseName()},setCourse:function(courseFile){var coursefile;coursefile=courseFile,coursefileElem.value=coursefile,updateCourseName()}}}(),langController=function(){const languageElem=document.getElementById("id_language");return{getSelectedLanguage:function(){return languageElem.value},setLanguage:function(lang){if(!function(lang){return courseController.getSelectedCourse().languages.includes(lang)}(lang))throw new Error("Selected language not available");languageElem.value=lang,courseController.updateCourseName()}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element"),isGradedElem=document.getElementById("id_mumie_isgraded");function updateName(){const newHeadline=function(task){if(!task)return null;const selectedLanguage=langController.getSelectedLanguage(),headlineWrapper=task.headline.find((localHeadline=>localHeadline.language===selectedLanguage));return headlineWrapper?headlineWrapper.name:null}(taskController.getSelectedTask());(function(){if(0===nameElem.value.length)return!1;return!serverController.getAllServers().flatMap((server=>server.courses)).flatMap((course=>course.tasks)).flatMap((task=>task.headline)).map((headline=>headline.name)).concat(courseController.getSelectedCourse().name.map((n=>n.value))).includes(nameElem.value)})()||(nameElem.value=newHeadline),taskDisplayElement.value=newHeadline}function getLocalizedLinkFromTask(task){return task.link+"?lang="+langController.getSelectedLanguage()}return{init:function(){updateName()},getSelectedTask:function(){const selectedLink=taskSelectionInput.value,selectedCourse=courseController.getSelectedCourse();if(!selectedCourse)return null;const tasks=selectedCourse.tasks.slice();return tasks.push(function(course){var headline=[];for(var i in course.name){var name=course.name[i];headline.push({name:name.value,language:name.language})}return{link:course.link,headline:headline}}(selectedCourse)),tasks.find((task=>getLocalizedLinkFromTask(task)===selectedLink))},setSelection:function(newSelection){taskSelectionInput.value=newSelection,updateName()},setIsGraded:function(isGraded){null===isGraded&&(isGradedElem.value=null),isGradedElem.value=isGraded?"1":"0",function(){const disabled="0"===isGradedElem.value;document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_duedate_enabled").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled}()},getGradingType:function(){const isGraded=isGradedElem.value;return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"}}}(),multiTaskEditController=function(){const propertySelectionInputs=document.getElementsByName("mumie_multi_edit_property"),selectedTaskProperties=document.getElementsByName("mumie_selected_task_properties")[0];let selectedTaskProp=[];const taskSelectionInputs=document.getElementsByName("mumie_multi_edit_task"),selectedTasks=document.getElementsByName("mumie_selected_tasks")[0];let selectedTaskIds=[];const sectionInputs=document.getElementsByName("mumie_multi_edit_section");return{init:function(){taskSelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskIds.push(checkbox.value):selectedTaskIds=selectedTaskIds.filter((elem=>elem!==checkbox.value)),selectedTasks.value=JSON.stringify(selectedTaskIds)}})),propertySelectionInputs.forEach((function(checkbox){checkbox.onchange=function(){checkbox.checked?selectedTaskProp.push(checkbox.value):selectedTaskProp=selectedTaskProp.filter((elem=>elem!==checkbox.value)),selectedTaskProperties.value=JSON.stringify(selectedTaskProp)}})),sectionInputs.forEach((function(sectionCheckbox){sectionCheckbox.onchange=function(){sectionCheckbox.checked?taskSelectionInputs.forEach((function(taskCheckbox){var array,element;taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!0,array=selectedTaskIds,element=taskCheckbox.value,array.includes(element)||array.push(element))})):taskSelectionInputs.forEach((function(taskCheckbox){taskCheckbox.getAttribute("section")===sectionCheckbox.value&&(taskCheckbox.checked=!1,selectedTaskIds=selectedTaskIds.filter((elem=>taskCheckbox.value!==elem)))})),selectedTasks.value=JSON.stringify(selectedTaskIds)}}))}}}();function disableDropDownMenus(errorKey){require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:errorKey,component:"mod_mumie"}]).done((function(s){notification.addNotification({message:s[0]+""+missingConfig.getAttribute("value")+"",type:"problem"})})).fail(notification.exception)})),serverController.disable(),problemSelectorController.disable()}return{init:function(contextid,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang;const isEdit=document.getElementById("id_name").getAttribute("value"),serverStructure=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);isEdit&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?disableDropDownMenus("mumie_form_missing_server"):serverStructure.length?(serverController.init(serverStructure),courseController.init(),taskController.init(isEdit),multiTaskEditController.init(),problemSelectorController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextid)}))}}})); //# sourceMappingURL=mod_form.min.js.map \ No newline at end of file diff --git a/amd/build/mod_form.min.js.map b/amd/build/mod_form.min.js.map index 853486f..ca3ed7c 100644 --- a/amd/build/mod_form.min.js.map +++ b/amd/build/mod_form.min.js.map @@ -1 +1 @@ -{"version":3,"file":"mod_form.min.js","sources":["../src/mod_form.js"],"sourcesContent":["define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_server_config', 'core/ajax'],\n function() {\n const addServerButton = document.getElementById(\"id_add_server_button\");\n const missingConfig = document.getElementsByName(\"mumie_missing_config\")[0];\n let lmsSelectorUrl;\n let systemLanguage;\n const serverController = (function() {\n let serverStructure;\n const serverDropDown = document.getElementById(\"id_server\");\n\n return {\n init: function(structure) {\n serverStructure = structure;\n },\n getSelectedServer: function() {\n const selectedServerName = serverDropDown.options[serverDropDown.selectedIndex].text;\n return serverStructure.find(server => server.name === selectedServerName);\n },\n disable: function() {\n serverDropDown.disabled = true;\n removeChildElems(serverDropDown);\n },\n getAllServers: function() {\n return serverStructure;\n }\n };\n })();\n\n const problemSelectorController = (function() {\n const problemSelectorButton = document.getElementById('id_prb_selector_btn');\n const multiProblemSelectorButton = document.getElementById('id_multi_problem_selector_btn');\n let problemSelectorWindow;\n const mumieOrg = document.getElementsByName('mumie_org')[0].value;\n\n /**\n * Send a message to the problem selector window.\n *\n * Don't do anything, if there is no problem selector window.\n * @param {Object} response\n */\n function sendResponse(response) {\n if (!problemSelectorWindow) {\n return;\n }\n problemSelectorWindow.postMessage(JSON.stringify(response), lmsSelectorUrl);\n }\n\n /**\n * Send a success message to problem selector window\n * @param {string} message\n */\n function sendSuccess(message = '') {\n sendResponse({\n success: true,\n message: message\n });\n }\n\n /**\n * Send a failure message to problem selector window\n * @param {string} message\n */\n function sendFailure(message = '') {\n sendResponse({\n success: false,\n message: message\n });\n }\n\n /**\n * Add an event listener that accepts messages from LMS-Browser and updates the selected problem.\n */\n function addMessageListener() {\n window.addEventListener('message', (event) => {\n if (event.origin !== lmsSelectorUrl) {\n return;\n }\n const importObj = JSON.parse(event.data);\n const isGraded = importObj.isGraded !== false;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link + '?lang=' + importObj.language);\n taskController.setIsGraded(isGraded);\n sendSuccess();\n window.focus();\n displayProblemSelectedMessage();\n } catch (error) {\n sendFailure(error.message);\n }\n }, false);\n }\n\n /**\n * Display a success message in Moodle that a problem was successfully selected.\n */\n function displayProblemSelectedMessage() {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': 'mumie_form_updated_selection',\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0],\n type: \"info\"\n });\n }).fail(notification.exception);\n });\n }\n\n return {\n init: function() {\n const gradingType = taskController.getGradingType();\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + 'org='\n + mumieOrg\n + '&serverUrl='\n + encodeURIComponent(serverController.getSelectedServer().urlprefix)\n + '&problemLang='\n + langController.getSelectedLanguage()\n + '&origin=' + encodeURIComponent(window.location.origin)\n + '&uiLang=' + systemLanguage\n + '&gradingType=' + gradingType\n + '&multiCourse=true'\n , '_blank'\n );\n };\n\n window.onclose = function() {\n sendSuccess();\n };\n\n window.addEventListener(\"beforeunload\", function() {\n sendSuccess();\n }, false);\n\n addMessageListener();\n\n multiProblemSelectorButton.onclick = function(e) {\n e.preventDefault();\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + \"serverUrl=\"\n + encodeURIComponent(serverController.getSelectedServer().urlprefix),\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n }\n };\n })();\n\n const courseController = (function() {\n const courseNameElem = document.getElementById(\"id_mumie_course\");\n const coursefileElem = document.getElementsByName(\"mumie_coursefile\")[0];\n\n\n /**\n * Update the hidden input field with the selected course's course file path\n *\n * @param {string} coursefile\n */\n function updateCoursefilePath(coursefile) {\n coursefileElem.value = coursefile;\n updateCourseName();\n }\n\n /**\n * Update displayed course name.\n */\n function updateCourseName() {\n const selectedCourse = courseController.getSelectedCourse();\n const selectedLanguage = langController.getSelectedLanguage();\n if (!selectedCourse || !selectedLanguage) {\n return;\n }\n courseNameElem.value = selectedCourse.name\n .find(translation => translation.language === selectedLanguage)?.value;\n }\n\n return {\n init: function() {\n updateCourseName();\n },\n getSelectedCourse: function() {\n const courses = serverController.getSelectedServer().courses;\n return courses.find(course => course.coursefile === coursefileElem.value);\n },\n updateCourseName: function() {\n updateCourseName();\n },\n setCourse: function(courseFile) {\n updateCoursefilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n\n /**\n * Check if the given language exists in the currently selected course.\n * @param {string} lang\n * @returns {boolean} Whether the language exists\n */\n function languageExists(lang) {\n return courseController.getSelectedCourse().languages.includes(lang);\n }\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n if (!languageExists(lang)) {\n throw new Error(\"Selected language not available\");\n }\n languageElem.value = lang;\n courseController.updateCourseName();\n }\n };\n })();\n\n const taskController = (function() {\n const taskSelectionInput = document.getElementsByName(\"taskurl\")[0];\n const nameElem = document.getElementById(\"id_name\");\n const taskDisplayElement = document.getElementById(\"id_task_display_element\");\n const isGradedElem = document.getElementById('id_mumie_isgraded');\n\n\n /**\n * Update the activity's name in the input field\n */\n function updateName() {\n const newHeadline = getHeadline(taskController.getSelectedTask());\n if (!isCustomName()) {\n nameElem.value = newHeadline;\n }\n taskDisplayElement.value = newHeadline;\n }\n\n /**\n * Check whether the activity has a custom name\n *\n * @return {boolean} True, if there is no headline with that name in all tasks\n */\n function isCustomName() {\n if (nameElem.value.length === 0) {\n return false;\n }\n return !getAllHeadlines().includes(nameElem.value);\n }\n\n /**\n * Get the task's headline for the currently selected language\n * @param {Object} task\n * @returns {string|null} the headline\n */\n function getHeadline(task) {\n if (!task) {\n return null;\n }\n const selectedLanguage = langController.getSelectedLanguage();\n const headlineWrapper = task.headline.find(localHeadline => localHeadline.language === selectedLanguage);\n return headlineWrapper ? headlineWrapper.name : null;\n }\n\n /**\n * Get all tasks that are available on all servers\n *\n * @return {Object} Array containing all available tasks\n */\n function getAllTasks() {\n return serverController.getAllServers()\n .flatMap(server => server.courses)\n .flatMap(course => course.tasks);\n }\n\n /**\n * Get all possible headlines in all languages\n * @returns {Object} Array containing all headlines\n */\n function getAllHeadlines() {\n return getAllTasks().flatMap(task => task.headline)\n .map(headline => headline.name)\n .concat(courseController.getSelectedCourse().name.map(n => n.value));\n }\n\n /**\n * Add language parameter to the task's link to display content in the selected language\n * @param {Object} task\n * @returns {string}\n */\n function getLocalizedLinkFromTask(task) {\n return getLocalizedLink(task.link);\n }\n\n /**\n * Add language parameter to link\n * @param {string} link\n * @returns {string}\n */\n function getLocalizedLink(link) {\n return link + \"?lang=\" + langController.getSelectedLanguage();\n }\n\n /**\n * Form inputs related to grades should be disabled, if the MUMIE Task is not graded.\n */\n function updateGradeEditability() {\n const disabled = isGradedElem.value === '0';\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_duedate_enabled').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n }\n\n /**\n * Get a task that links to a course's overview page\n * @param {Object} course\n * @returns {Object} task\n */\n function getPseudoTaskFromCourse(course) {\n var headline = [];\n for (var i in course.name) {\n var name = course.name[i];\n headline.push({\n \"name\": name.value,\n \"language\": name.language\n });\n }\n return {\n \"link\": course.link,\n \"headline\": headline\n };\n }\n\n return {\n init: function() {\n updateName();\n },\n getSelectedTask: function() {\n const selectedLink = taskSelectionInput.value;\n const selectedCourse = courseController.getSelectedCourse();\n if (!selectedCourse) {\n return null;\n }\n const tasks = selectedCourse\n .tasks\n .slice();\n tasks.push(getPseudoTaskFromCourse(selectedCourse));\n return tasks\n .find(task => getLocalizedLinkFromTask(task) === selectedLink);\n },\n setSelection: function(newSelection) {\n taskSelectionInput.value = newSelection;\n updateName();\n },\n setIsGraded: function(isGraded) {\n if (isGraded === null) {\n isGradedElem.value = null;\n }\n isGradedElem.value = isGraded ? '1' : '0';\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = isGradedElem.value;\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n }\n };\n })();\n\n\n const multiTaskEditController = (function() {\n const propertySelectionInputs = document.getElementsByName(\"mumie_multi_edit_property\");\n const selectedTaskProperties = document.getElementsByName(\"mumie_selected_task_properties\")[0];\n let selectedTaskProp = [];\n const taskSelectionInputs = document.getElementsByName(\"mumie_multi_edit_task\");\n const selectedTasks = document.getElementsByName(\"mumie_selected_tasks\")[0];\n let selectedTaskIds = [];\n const sectionInputs = document.getElementsByName(\"mumie_multi_edit_section\");\n\n /**\n * Push an element to an array, if it's not already included.\n *\n * @param {string[]} array\n * @param {string} element\n */\n function pushIfNotExists(array, element) {\n if (!array.includes(element)) {\n array.push(element);\n }\n }\n\n /**\n * Set selection listeners for other MUMIE Tasks in the course.\n */\n function setTaskSelectionListeners() {\n taskSelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskIds = selectedTaskIds.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskIds.push(checkbox.value);\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n /**\n * Set selection listeners for properties to apply to MUMIE Tasks in the course.\n */\n function setPropertySelectionListeners() {\n propertySelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskProp = selectedTaskProp.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskProp.push(checkbox.value);\n }\n selectedTaskProperties.value = JSON.stringify(selectedTaskProp);\n };\n });\n }\n\n /**\n * Set selection listeners for entire section of MUMIE Tasks in the course\n */\n function setSectionSelectionListeners() {\n sectionInputs.forEach(function(sectionCheckbox) {\n sectionCheckbox.onchange = function() {\n if (!sectionCheckbox.checked) {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = false;\n selectedTaskIds = selectedTaskIds.filter(elem => taskCheckbox.value !== elem);\n }\n });\n } else {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = true;\n pushIfNotExists(selectedTaskIds, taskCheckbox.value);\n }\n });\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n return {\n init: function() {\n setTaskSelectionListeners();\n setPropertySelectionListeners();\n setSectionSelectionListeners();\n },\n };\n })();\n\n /**\n * Disable all dropdown menus and show notification\n * @param {string} errorKey\n */\n function disableDropDownMenus(errorKey) {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': errorKey,\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0] + \"\" + missingConfig.getAttribute(\"value\") + \"\",\n type: \"problem\"\n });\n }).fail(notification.exception);\n });\n serverController.disable();\n problemSelectorController.disable();\n }\n\n return {\n init: function(contextid, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n const isEdit = document.getElementById(\"id_name\").getAttribute('value');\n const serverStructure = JSON.parse(document.getElementsByName('mumie_server_structure')[0].value);\n if (isEdit && !serverConfigExists()) {\n disableDropDownMenus('mumie_form_missing_server');\n } else if (!serverStructure.length) {\n disableDropDownMenus('mumie_form_no_server_conf');\n } else {\n serverController.init(serverStructure);\n courseController.init();\n taskController.init(isEdit);\n multiTaskEditController.init();\n problemSelectorController.init();\n }\n multiTaskEditController.init();\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextid);\n });\n }\n }\n };\n\n /**\n * Remove all child elements of a given html element\n * @param {Object} elem\n */\n function removeChildElems(elem) {\n while (elem.firstChild) {\n elem.removeChild(elem.firstChild);\n }\n }\n\n /**\n * Check, if the flag for an existing config is set\n * @returns {boolean}\n */\n function serverConfigExists() {\n return document.getElementsByName(\"mumie_missing_config\")[0].getAttribute(\"value\") === \"\";\n }\n });\n"],"names":["define","lmsSelectorUrl","systemLanguage","serverStructure","serverDropDown","languageElem","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","addServerButton","document","getElementById","missingConfig","getElementsByName","serverController","init","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","getAllServers","problemSelectorController","problemSelectorWindow","problemSelectorButton","multiProblemSelectorButton","mumieOrg","value","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","window","addEventListener","event","origin","importObj","parse","data","isGraded","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","gradingType","getGradingType","onclick","open","encodeURIComponent","urlprefix","getSelectedLanguage","location","onclose","e","preventDefault","courseNameElem","coursefileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","lang","languages","includes","languageExists","Error","taskSelectionInput","nameElem","taskDisplayElement","isGradedElem","updateName","newHeadline","task","headlineWrapper","headline","localHeadline","getHeadline","getSelectedTask","length","flatMap","tasks","map","concat","n","isCustomName","getLocalizedLinkFromTask","selectedLink","slice","push","i","getPseudoTaskFromCourse","newSelection","multiTaskEditController","forEach","checkbox","onchange","checked","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","disableDropDownMenus","errorKey","contextid","prbSelectorUrl","isEdit","MumieServer"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"mod_form.min.js","sources":["../src/mod_form.js"],"sourcesContent":["define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_server_config', 'core/ajax'],\n function() {\n const addServerButton = document.getElementById(\"id_add_server_button\");\n const missingConfig = document.getElementsByName(\"mumie_missing_config\")[0];\n let lmsSelectorUrl;\n let systemLanguage;\n const serverController = (function() {\n let serverStructure;\n const serverDropDown = document.getElementById(\"id_server\");\n\n return {\n init: function(structure) {\n serverStructure = structure;\n },\n getSelectedServer: function() {\n const selectedServerName = serverDropDown.options[serverDropDown.selectedIndex].text;\n return serverStructure.find(server => server.name === selectedServerName);\n },\n disable: function() {\n serverDropDown.disabled = true;\n removeChildElems(serverDropDown);\n },\n getAllServers: function() {\n return serverStructure;\n }\n };\n })();\n\n const problemSelectorController = (function() {\n const problemSelectorButton = document.getElementById('id_prb_selector_btn');\n const multiProblemSelectorButton = document.getElementById('id_multi_problem_selector_btn');\n let problemSelectorWindow;\n const mumieOrg = document.getElementsByName('mumie_org')[0].value;\n\n /**\n * Send a message to the problem selector window.\n *\n * Don't do anything, if there is no problem selector window.\n * @param {Object} response\n */\n function sendResponse(response) {\n if (!problemSelectorWindow) {\n return;\n }\n problemSelectorWindow.postMessage(JSON.stringify(response), lmsSelectorUrl);\n }\n\n /**\n * Send a success message to problem selector window\n * @param {string} message\n */\n function sendSuccess(message = '') {\n sendResponse({\n success: true,\n message: message\n });\n }\n\n /**\n * Send a failure message to problem selector window\n * @param {string} message\n */\n function sendFailure(message = '') {\n sendResponse({\n success: false,\n message: message\n });\n }\n\n /**\n * Add an event listener that accepts messages from LMS-Browser and updates the selected problem.\n */\n function addMessageListener() {\n window.addEventListener('message', (event) => {\n if (event.origin !== lmsSelectorUrl) {\n return;\n }\n const importObj = JSON.parse(event.data);\n const isGraded = importObj.isGraded !== false;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link + '?lang=' + importObj.language);\n taskController.setIsGraded(isGraded);\n sendSuccess();\n window.focus();\n displayProblemSelectedMessage();\n } catch (error) {\n sendFailure(error.message);\n }\n }, false);\n }\n\n /**\n * Display a success message in Moodle that a problem was successfully selected.\n */\n function displayProblemSelectedMessage() {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': 'mumie_form_updated_selection',\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0],\n type: \"info\"\n });\n }).fail(notification.exception);\n });\n }\n\n return {\n init: function() {\n const gradingType = taskController.getGradingType();\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + 'org='\n + mumieOrg\n + '&serverUrl='\n + encodeURIComponent(serverController.getSelectedServer().urlprefix)\n + '&problemLang='\n + langController.getSelectedLanguage()\n + '&origin=' + encodeURIComponent(window.location.origin)\n + '&uiLang=' + systemLanguage\n + '&gradingType=' + gradingType\n + '&multiCourse=true'\n , '_blank'\n );\n };\n\n window.onclose = function() {\n sendSuccess();\n };\n\n window.addEventListener(\"beforeunload\", function() {\n sendSuccess();\n }, false);\n\n addMessageListener();\n\n multiProblemSelectorButton.onclick = function(e) {\n e.preventDefault();\n problemSelectorWindow = window.open(\n lmsSelectorUrl\n + '/lms-problem-selector?'\n + \"serverUrl=\"\n + encodeURIComponent(serverController.getSelectedServer().urlprefix),\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n }\n };\n })();\n\n const courseController = (function() {\n const courseNameElem = document.getElementById(\"id_mumie_course\");\n const coursefileElem = document.getElementsByName(\"mumie_coursefile\")[0];\n\n\n /**\n * Update the hidden input field with the selected course's course file path\n *\n * @param {string} coursefile\n */\n function updateCoursefilePath(coursefile) {\n coursefileElem.value = coursefile;\n updateCourseName();\n }\n\n /**\n * Update displayed course name.\n */\n function updateCourseName() {\n const selectedCourse = courseController.getSelectedCourse();\n const selectedLanguage = langController.getSelectedLanguage();\n if (!selectedCourse || !selectedLanguage) {\n return;\n }\n courseNameElem.value = selectedCourse.name\n .find(translation => translation.language === selectedLanguage)?.value;\n }\n\n return {\n init: function() {\n updateCourseName();\n },\n getSelectedCourse: function() {\n const courses = serverController.getSelectedServer().courses;\n return courses.find(course => course.coursefile === coursefileElem.value);\n },\n updateCourseName: function() {\n updateCourseName();\n },\n setCourse: function(courseFile) {\n updateCoursefilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n\n /**\n * Check if the given language exists in the currently selected course.\n * @param {string} lang\n * @returns {boolean} Whether the language exists\n */\n function languageExists(lang) {\n return courseController.getSelectedCourse().languages.includes(lang);\n }\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n if (!languageExists(lang)) {\n throw new Error(\"Selected language not available\");\n }\n languageElem.value = lang;\n courseController.updateCourseName();\n }\n };\n })();\n\n const taskController = (function() {\n const taskSelectionInput = document.getElementsByName(\"taskurl\")[0];\n const nameElem = document.getElementById(\"id_name\");\n const taskDisplayElement = document.getElementById(\"id_task_display_element\");\n const isGradedElem = document.getElementById('id_mumie_isgraded');\n\n\n /**\n * Update the activity's name in the input field\n */\n function updateName() {\n const newHeadline = getHeadline(taskController.getSelectedTask());\n if (!isCustomName()) {\n nameElem.value = newHeadline;\n }\n taskDisplayElement.value = newHeadline;\n }\n\n /**\n * Check whether the activity has a custom name\n *\n * @return {boolean} True, if there is no headline with that name in all tasks\n */\n function isCustomName() {\n if (nameElem.value.length === 0) {\n return false;\n }\n return !getAllHeadlines().includes(nameElem.value);\n }\n\n /**\n * Get the task's headline for the currently selected language\n * @param {Object} task\n * @returns {string|null} the headline\n */\n function getHeadline(task) {\n if (!task) {\n return null;\n }\n const selectedLanguage = langController.getSelectedLanguage();\n const headlineWrapper = task.headline.find(localHeadline => localHeadline.language === selectedLanguage);\n return headlineWrapper ? headlineWrapper.name : null;\n }\n\n /**\n * Get all tasks that are available on all servers\n *\n * @return {Object} Array containing all available tasks\n */\n function getAllTasks() {\n return serverController.getAllServers()\n .flatMap(server => server.courses)\n .flatMap(course => course.tasks);\n }\n\n /**\n * Get all possible headlines in all languages\n * @returns {Object} Array containing all headlines\n */\n function getAllHeadlines() {\n return getAllTasks().flatMap(task => task.headline)\n .map(headline => headline.name)\n .concat(courseController.getSelectedCourse().name.map(n => n.value));\n }\n\n /**\n * Add language parameter to the task's link to display content in the selected language\n * @param {Object} task\n * @returns {string}\n */\n function getLocalizedLinkFromTask(task) {\n return getLocalizedLink(task.link);\n }\n\n /**\n * Add language parameter to link\n * @param {string} link\n * @returns {string}\n */\n function getLocalizedLink(link) {\n return link + \"?lang=\" + langController.getSelectedLanguage();\n }\n\n /**\n * Form inputs related to grades should be disabled, if the MUMIE Task is not graded.\n */\n function updateGradeEditability() {\n const disabled = isGradedElem.value === '0';\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_duedate_enabled').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n }\n\n /**\n * Get a task that links to a course's overview page\n * @param {Object} course\n * @returns {Object} task\n */\n function getPseudoTaskFromCourse(course) {\n var headline = [];\n for (var i in course.name) {\n var name = course.name[i];\n headline.push({\n \"name\": name.value,\n \"language\": name.language\n });\n }\n return {\n \"link\": course.link,\n \"headline\": headline\n };\n }\n\n return {\n init: function() {\n updateName();\n },\n getSelectedTask: function() {\n const selectedLink = taskSelectionInput.value;\n const selectedCourse = courseController.getSelectedCourse();\n if (!selectedCourse) {\n return null;\n }\n const tasks = selectedCourse\n .tasks\n .slice();\n tasks.push(getPseudoTaskFromCourse(selectedCourse));\n return tasks\n .find(task => getLocalizedLinkFromTask(task) === selectedLink);\n },\n setSelection: function(newSelection) {\n taskSelectionInput.value = newSelection;\n updateName();\n },\n setIsGraded: function(isGraded) {\n if (isGraded === null) {\n isGradedElem.value = null;\n }\n isGradedElem.value = isGraded ? '1' : '0';\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = isGradedElem.value;\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n }\n };\n })();\n\n\n const multiTaskEditController = (function() {\n const propertySelectionInputs = document.getElementsByName(\"mumie_multi_edit_property\");\n const selectedTaskProperties = document.getElementsByName(\"mumie_selected_task_properties\")[0];\n let selectedTaskProp = [];\n const taskSelectionInputs = document.getElementsByName(\"mumie_multi_edit_task\");\n const selectedTasks = document.getElementsByName(\"mumie_selected_tasks\")[0];\n let selectedTaskIds = [];\n const sectionInputs = document.getElementsByName(\"mumie_multi_edit_section\");\n\n /**\n * Push an element to an array, if it's not already included.\n *\n * @param {string[]} array\n * @param {string} element\n */\n function pushIfNotExists(array, element) {\n if (!array.includes(element)) {\n array.push(element);\n }\n }\n\n /**\n * Set selection listeners for other MUMIE Tasks in the course.\n */\n function setTaskSelectionListeners() {\n taskSelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskIds = selectedTaskIds.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskIds.push(checkbox.value);\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n /**\n * Set selection listeners for properties to apply to MUMIE Tasks in the course.\n */\n function setPropertySelectionListeners() {\n propertySelectionInputs.forEach(function(checkbox) {\n checkbox.onchange = function() {\n if (!checkbox.checked) {\n selectedTaskProp = selectedTaskProp.filter(elem => elem !== checkbox.value);\n } else {\n selectedTaskProp.push(checkbox.value);\n }\n selectedTaskProperties.value = JSON.stringify(selectedTaskProp);\n };\n });\n }\n\n /**\n * Set selection listeners for entire section of MUMIE Tasks in the course\n */\n function setSectionSelectionListeners() {\n sectionInputs.forEach(function(sectionCheckbox) {\n sectionCheckbox.onchange = function() {\n if (!sectionCheckbox.checked) {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = false;\n selectedTaskIds = selectedTaskIds.filter(elem => taskCheckbox.value !== elem);\n }\n });\n } else {\n taskSelectionInputs.forEach(function(taskCheckbox) {\n if (taskCheckbox.getAttribute('section') === sectionCheckbox.value) {\n taskCheckbox.checked = true;\n pushIfNotExists(selectedTaskIds, taskCheckbox.value);\n }\n });\n }\n selectedTasks.value = JSON.stringify(selectedTaskIds);\n };\n });\n }\n\n return {\n init: function() {\n setTaskSelectionListeners();\n setPropertySelectionListeners();\n setSectionSelectionListeners();\n },\n };\n })();\n\n /**\n * Disable all dropdown menus and show notification\n * @param {string} errorKey\n */\n function disableDropDownMenus(errorKey) {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': errorKey,\n component: 'mod_mumie'\n }]).done(function(s) {\n notification.addNotification({\n message: s[0] + \"\" + missingConfig.getAttribute(\"value\") + \"\",\n type: \"problem\"\n });\n }).fail(notification.exception);\n });\n serverController.disable();\n problemSelectorController.disable();\n }\n\n return {\n init: function(contextid, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n const isEdit = document.getElementById(\"id_name\").getAttribute('value');\n const serverStructure = JSON.parse(document.getElementsByName('mumie_server_structure')[0].value);\n if (isEdit && !serverConfigExists()) {\n disableDropDownMenus('mumie_form_missing_server');\n } else if (!serverStructure.length) {\n disableDropDownMenus('mumie_form_no_server_conf');\n } else {\n serverController.init(serverStructure);\n courseController.init();\n taskController.init(isEdit);\n multiTaskEditController.init();\n problemSelectorController.init();\n }\n multiTaskEditController.init();\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextid);\n });\n }\n }\n };\n\n /**\n * Remove all child elements of a given html element\n * @param {Object} elem\n */\n function removeChildElems(elem) {\n while (elem.firstChild) {\n elem.removeChild(elem.firstChild);\n }\n }\n\n /**\n * Check, if the flag for an existing config is set\n * @returns {boolean}\n */\n function serverConfigExists() {\n return document.getElementsByName(\"mumie_missing_config\")[0].getAttribute(\"value\") === \"\";\n }\n });\n"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","serverController","serverStructure","serverDropDown","init","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","getAllServers","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","value","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","window","addEventListener","event","origin","importObj","parse","data","isGraded","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","gradingType","getGradingType","onclick","open","encodeURIComponent","urlprefix","getSelectedLanguage","location","onclose","e","preventDefault","courseNameElem","coursefileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","languages","includes","languageExists","Error","taskSelectionInput","nameElem","taskDisplayElement","isGradedElem","updateName","newHeadline","task","headlineWrapper","headline","localHeadline","getHeadline","getSelectedTask","length","flatMap","tasks","map","concat","n","isCustomName","getLocalizedLinkFromTask","selectedLink","slice","push","i","getPseudoTaskFromCourse","newSelection","updateGradeEditability","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","onchange","checked","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","disableDropDownMenus","errorKey","contextid","prbSelectorUrl","isEdit","MumieServer"],"mappings":"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"} \ No newline at end of file From 800280cfa9a4a80e1774cec28682ce0f0d569520 Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 23 Feb 2023 17:31:34 +0100 Subject: [PATCH 08/10] Fixing broken pipeline --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5a28b34..1039f01 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false matrix: include: - - php: '7.4' + - php: '8.0' moodle-branch: 'master' database: 'pgsql' - php: '7.4' From 07e627f75090a264ea623915adf1d5e324705d5f Mon Sep 17 00:00:00 2001 From: tobias Date: Thu, 23 Feb 2023 17:51:05 +0100 Subject: [PATCH 09/10] Removed testing against moodle master as it changes and behaves unreliably --- .github/workflows/main.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1039f01..702e14e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,9 +15,6 @@ jobs: fail-fast: false matrix: include: - - php: '8.0' - moodle-branch: 'master' - database: 'pgsql' - php: '7.4' moodle-branch: 'MOODLE_401_STABLE' database: 'mariadb' From 17c718a76576d02dc209c1d49e7dceeb11664228 Mon Sep 17 00:00:00 2001 From: tobias Date: Mon, 27 Feb 2023 10:41:13 +0100 Subject: [PATCH 10/10] Updated changelog and version --- changelog.md | 2 +- version.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 2f2caf5..a62b30b 100644 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,7 @@ All important changes to this plugin will be documented in this file. -## [v1.4.10] - TODO +## [v1.4.10] - 2023-02-27 ### Changed - Button to open a MUMIE Task in grading view is moved on top of the participant list diff --git a/version.php b/version.php index 4e81cbd..63f2c5c 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2023021311; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2023022700; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2022041900; $plugin->release = "v1.4.9";