From af4c12783dd363f77a1c4bbeb325d77e5d6181ab Mon Sep 17 00:00:00 2001 From: Lyannic Date: Mon, 12 Jan 2026 18:43:52 +0100 Subject: [PATCH 001/101] Follow Moodle Code Style (cherry picked from commit 94d2b550de0043980890125f57ac64d156148e8f) --- .../backup_mumie_activity_task.class.php | 1 - backup/moodle2/backup_mumie_stepslib.php | 1 - backup/moodle2/restore_mumie_stepslib.php | 1 - .../context/context_provider.php | 2 +- .../context/object_context.php | 2 +- ...e_standard_top_of_body_html_generation.php | 3 +- .../mumie_calendar_service.php | 10 ++--- .../mumie_individual_calendar_service.php | 8 ++-- classes/mumie_dndupload_processor.php | 10 +++-- classes/mumie_duedate_extension.php | 2 +- classes/mumie_grader.php | 3 +- classes/mumie_participants.php | 10 +++-- classes/observer.php | 1 - classes/privacy/provider.php | 7 +-- db/upgrade.php | 43 +++++++++++++++---- forms/duedate_form.php | 2 +- forms/mumie_task_validator.php | 2 +- lib.php | 22 +++++----- locallib.php | 1 - mod_form.php | 34 ++++++++------- tests/privacy_provider_test.php | 3 -- view.php | 7 +-- 22 files changed, 101 insertions(+), 74 deletions(-) diff --git a/backup/moodle2/backup_mumie_activity_task.class.php b/backup/moodle2/backup_mumie_activity_task.class.php index 51a02548..cb14eb90 100644 --- a/backup/moodle2/backup_mumie_activity_task.class.php +++ b/backup/moodle2/backup_mumie_activity_task.class.php @@ -35,7 +35,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class backup_mumie_activity_task extends backup_activity_task { - /** * Define (add) particular settings this activity can have */ diff --git a/backup/moodle2/backup_mumie_stepslib.php b/backup/moodle2/backup_mumie_stepslib.php index 86641680..5bc9ccc7 100644 --- a/backup/moodle2/backup_mumie_stepslib.php +++ b/backup/moodle2/backup_mumie_stepslib.php @@ -23,7 +23,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class backup_mumie_structure_step extends backup_activity_structure_step { - /** * Defines structure of MUMIE tasks in the backup file */ diff --git a/backup/moodle2/restore_mumie_stepslib.php b/backup/moodle2/restore_mumie_stepslib.php index 4683499d..c9b308e4 100644 --- a/backup/moodle2/restore_mumie_stepslib.php +++ b/backup/moodle2/restore_mumie_stepslib.php @@ -22,7 +22,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class restore_mumie_activity_structure_step extends restore_activity_structure_step { - /** * define the structure for restoration process */ diff --git a/classes/grades/synchronization/context/context_provider.php b/classes/grades/synchronization/context/context_provider.php index 4e8e2cad..f61cfa72 100644 --- a/classes/grades/synchronization/context/context_provider.php +++ b/classes/grades/synchronization/context/context_provider.php @@ -57,7 +57,7 @@ public static function get_context(array $mumietasks, array $users): context { * @return bool */ public static function requires_context(stdClass $mumie): bool { - return (substr( $mumie->taskurl, 0, 10 ) === "worksheet_") + return (substr($mumie->taskurl, 0, 10) === "worksheet_") && ($mumie->duedate > 0 || $mumie->timelimit > 0); } diff --git a/classes/grades/synchronization/context/object_context.php b/classes/grades/synchronization/context/object_context.php index 6c9eac33..ff5939fd 100644 --- a/classes/grades/synchronization/context/object_context.php +++ b/classes/grades/synchronization/context/object_context.php @@ -50,7 +50,7 @@ public function __construct($lang) { * @param user_context $usercontext * @return void */ - public function add_user_context(string $userid, user_context $usercontext): void { + public function add_user_context(string $userid, user_context $usercontext): void { $this->usercontexts[$userid] = $usercontext; } diff --git a/classes/hook/output/before_standard_top_of_body_html_generation.php b/classes/hook/output/before_standard_top_of_body_html_generation.php index 950babc2..4dcb72d6 100644 --- a/classes/hook/output/before_standard_top_of_body_html_generation.php +++ b/classes/hook/output/before_standard_top_of_body_html_generation.php @@ -40,8 +40,7 @@ * @author Yannic Lapawczyk (yannic.lapawczyk@integral-learning.de) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -final class before_standard_top_of_body_html_generation implements described_hook, deprecated_callback_replacement { - +final class before_standard_top_of_body_html_generation implements deprecated_callback_replacement, described_hook { /** * Hook description. */ diff --git a/classes/mumie_calendar_service/mumie_calendar_service.php b/classes/mumie_calendar_service/mumie_calendar_service.php index b11c269e..a79e3501 100644 --- a/classes/mumie_calendar_service/mumie_calendar_service.php +++ b/classes/mumie_calendar_service/mumie_calendar_service.php @@ -35,8 +35,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class mumie_calendar_service { - - /** * The MUMIE Task we want to manage calendar entries for. * @@ -73,7 +71,7 @@ class mumie_calendar_service { */ public function __construct($mumie) { global $CFG; - require_once($CFG->dirroot.'/mod/mumie/locallib.php'); + require_once($CFG->dirroot . '/mod/mumie/locallib.php'); if (!is_object($mumie)) { $mumie = locallib::get_mumie_task($mumie); @@ -117,7 +115,7 @@ public function update() { */ protected function create_calendar_event($eventtype, $timestart, $userid = null) { global $CFG; - require_once($CFG->dirroot.'/calendar/lib.php'); + require_once($CFG->dirroot . '/calendar/lib.php'); $event = new \stdClass(); $event->type = CALENDAR_EVENT_TYPE_ACTION; $event->eventtype = $eventtype; @@ -146,7 +144,7 @@ protected function create_calendar_event($eventtype, $timestart, $userid = null) */ protected function get_calendar_event($type, $userid = null) { global $CFG, $DB; - require_once($CFG->dirroot.'/calendar/lib.php'); + require_once($CFG->dirroot . '/calendar/lib.php'); $params = [ "modulename" => "mumie", @@ -177,7 +175,7 @@ protected function get_calendar_event($type, $userid = null) { */ public static function delete_all_calendar_events($mumie) { global $CFG, $DB; - require_once($CFG->dirroot.'/calendar/lib.php'); + require_once($CFG->dirroot . '/calendar/lib.php'); $records = $DB->get_records( "event", [ diff --git a/classes/mumie_calendar_service/mumie_individual_calendar_service.php b/classes/mumie_calendar_service/mumie_individual_calendar_service.php index 4718319c..57778cad 100644 --- a/classes/mumie_calendar_service/mumie_individual_calendar_service.php +++ b/classes/mumie_calendar_service/mumie_individual_calendar_service.php @@ -28,8 +28,8 @@ defined('MOODLE_INTERNAL') || die; -require_once($CFG->dirroot.'/mod/mumie/classes/mumie_duedate_extension.php'); -require_once($CFG->dirroot.'/mod/mumie/classes/mumie_calendar_service/mumie_calendar_service.php'); +require_once($CFG->dirroot . '/mod/mumie/classes/mumie_duedate_extension.php'); +require_once($CFG->dirroot . '/mod/mumie/classes/mumie_calendar_service/mumie_calendar_service.php'); /** * Class manages individual calendar entries for MUMIE Tasks. @@ -97,8 +97,8 @@ public function __construct($mumie, $userid = 0) { */ public function update() { global $CFG; - require_once($CFG->dirroot.'/mod/mumie/locallib.php'); - require_once($CFG->dirroot.'/mod/mumie/classes/mumie_duedate_extension.php'); + require_once($CFG->dirroot . '/mod/mumie/locallib.php'); + require_once($CFG->dirroot . '/mod/mumie/classes/mumie_duedate_extension.php'); if (!$this->extension->get_duedate() && $this->event) { $this->event->delete(); diff --git a/classes/mumie_dndupload_processor.php b/classes/mumie_dndupload_processor.php index 2d3118ee..bd55925c 100644 --- a/classes/mumie_dndupload_processor.php +++ b/classes/mumie_dndupload_processor.php @@ -240,9 +240,11 @@ private function get_course_gradepool_setting() { * @param \stdClass $uploadinstance a problem instance that's being imported */ private function validate_upload_params($uploadinstance) { - if (empty($uploadinstance->link) || empty($uploadinstance->path_to_coursefile) + if ( + empty($uploadinstance->link) || empty($uploadinstance->path_to_coursefile) || empty($uploadinstance->language) || empty($uploadinstance->name) - || empty($uploadinstance->server) || empty($uploadinstance->course)) { + || empty($uploadinstance->server) || empty($uploadinstance->course) + ) { throw new \moodle_exception('parameter_missing', 'mod_mumie'); } } @@ -284,8 +286,8 @@ private function create_mumie_course_module($mumie) { */ private function create_course_module() { global $CFG; - require_once($CFG->dirroot.'/course/modlib.php'); - list($module, $context, $cw, $cm, $data) = prepare_new_moduleinfo_data($this->course, 'mumie', $this->section); + require_once($CFG->dirroot . '/course/modlib.php'); + [$module, $context, $cw, $cm, $data] = prepare_new_moduleinfo_data($this->course, 'mumie', $this->section); $data->coursemodule = $data->id = add_course_module($data); return $data; } diff --git a/classes/mumie_duedate_extension.php b/classes/mumie_duedate_extension.php index 014be183..134e6b42 100644 --- a/classes/mumie_duedate_extension.php +++ b/classes/mumie_duedate_extension.php @@ -175,7 +175,7 @@ public static function from_object($object) { */ public static function from_objects($objects) { return array_map( - function($object) { + function ($object) { return self::from_object($object); }, $objects diff --git a/classes/mumie_grader.php b/classes/mumie_grader.php index 23531ffc..fc0bf8a4 100644 --- a/classes/mumie_grader.php +++ b/classes/mumie_grader.php @@ -153,7 +153,8 @@ public function view_submissions($userid) { if ($grades) { usort( - $grades, function ($a, $b) { + $grades, + function ($a, $b) { return $b->timecreated <=> $a->timecreated; } ); diff --git a/classes/mumie_participants.php b/classes/mumie_participants.php index 8604e2bb..746be244 100644 --- a/classes/mumie_participants.php +++ b/classes/mumie_participants.php @@ -205,7 +205,7 @@ private function add_duedate_button($extension) { * @param bool $useinitialsbar do you want to use the initials bar. */ public function query_db($pagesize, $useinitialsbar = true) { - list($twhere, $tparams) = $this->get_sql_where(); + [$twhere, $tparams] = $this->get_sql_where(); $psearch = new participants_search($this->course, $this->context, $this->filterset); $sort = $this->get_sql_sort(); @@ -226,8 +226,12 @@ public function query_db($pagesize, $useinitialsbar = true) { $rawdata->close(); if ($this->rawdata) { - $this->allroleassignments = get_users_roles($this->context, array_keys($this->rawdata), - true, 'c.contextlevel DESC, r.sortorder ASC'); + $this->allroleassignments = get_users_roles( + $this->context, + array_keys($this->rawdata), + true, + 'c.contextlevel DESC, r.sortorder ASC' + ); } else { $this->allroleassignments = []; } diff --git a/classes/observer.php b/classes/observer.php index 8a338ced..70e33818 100644 --- a/classes/observer.php +++ b/classes/observer.php @@ -40,7 +40,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class observer { - /** * Handle course_module_viewed event. * diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 6f59bb45..48a7db41 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -39,10 +39,7 @@ * @author Tobias Goltz (tobias.goltz@integral-learning.de) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements - \core_privacy\local\metadata\provider, - \core_privacy\local\request\plugin\provider, - \core_privacy\local\request\core_userlist_provider { +class provider implements \core_privacy\local\request\core_userlist_provider, \core_privacy\local\metadata\provider, \core_privacy\local\request\plugin\provider { /** * Returns meta data about this system. * @@ -212,7 +209,7 @@ public static function delete_data_for_users(approved_userlist $userlist) { $userids = $userlist->get_userids(); if ($context instanceof \context_module && count($userids) > 0) { - list($insql, $inparams) = $DB->get_in_or_equal($userids); + [$insql, $inparams] = $DB->get_in_or_equal($userids); $sql = "id IN ( SELECT id FROM ( diff --git a/db/upgrade.php b/db/upgrade.php index 3ecc8bdb..cf8cbd60 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -44,7 +44,7 @@ function xmldb_mumie_upgrade($oldversion) { upgrade_plugin_savepoint(true, 2019110100, 'mod', 'mumie'); } if ($oldversion < 2020011702) { - addfieldifmissing('mumie', 'duedate', XMLDB_TYPE_INTEGER, '10', null, null, null, '0', null); + addfieldifmissing('mumie', 'duedate', XMLDB_TYPE_INTEGER, '10', null, null, null, '0', null); addfieldifmissing('mumie', 'privategradepool', XMLDB_TYPE_INTEGER, '1', null, null, null, null, null); mumie_set_privategradepool_default(); upgrade_plugin_savepoint(true, 2020011702, 'mod', 'mumie'); @@ -56,10 +56,28 @@ function xmldb_mumie_upgrade($oldversion) { if ($oldversion < 2021011303) { addtableifmissing('mumie_duedate', 'id'); - addfieldifmissing('mumie_duedate', 'id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, - XMLDB_SEQUENCE, null, null); - addfieldifmissing('mumie_duedate', 'mumie', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, - null, null, null); + addfieldifmissing( + 'mumie_duedate', + 'id', + XMLDB_TYPE_INTEGER, + '10', + null, + XMLDB_NOTNULL, + XMLDB_SEQUENCE, + null, + null + ); + addfieldifmissing( + 'mumie_duedate', + 'mumie', + XMLDB_TYPE_INTEGER, + '10', + null, + XMLDB_NOTNULL, + null, + null, + null + ); addfieldifmissing('mumie_duedate', 'userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null); addfieldifmissing('mumie_duedate', 'duedate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null); upgrade_plugin_savepoint(true, 2021011303, 'mod', 'mumie'); @@ -87,7 +105,7 @@ function addtableifmissing(string $tablename, string $primaryname): void { global $DB; $dbman = $DB->get_manager(); if (!$dbman->table_exists($tablename)) { - $table = new xmldb_table ($tablename); + $table = new xmldb_table($tablename); $table->add_key('primary', XMLDB_KEY_PRIMARY, [$primaryname]); $dbman->create_table($table); } @@ -106,8 +124,17 @@ function addtableifmissing(string $tablename, string $primaryname): void { * @param null|string $previous * @return void */ -function addfieldifmissing(string $tablename, string $fieldname, ?int $type, ?string $precision, - ?bool $unsigned, ?bool $notnull, ?bool $sequence, mixed $default, ?string $previous): void { +function addfieldifmissing( + string $tablename, + string $fieldname, + ?int $type, + ?string $precision, + ?bool $unsigned, + ?bool $notnull, + ?bool $sequence, + mixed $default, + ?string $previous +): void { global $DB; $dbman = $DB->get_manager(); $table = new xmldb_table($tablename); diff --git a/forms/duedate_form.php b/forms/duedate_form.php index 34a69aaf..abc639ce 100644 --- a/forms/duedate_form.php +++ b/forms/duedate_form.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die; -require_once($CFG->dirroot.'/lib/formslib.php'); +require_once($CFG->dirroot . '/lib/formslib.php'); /** * This file describes a class used to display a form to create and edit due date extensions. diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index d83d4170..9addee74 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -73,7 +73,7 @@ private static function check_required(array $data): array { } $taskurlvalid = isset($data["taskurl"]) && $data["taskurl"] !== ""; - if (!$taskurlvalid && (!isset($data["mumie_missing_config"]) ||$data["mumie_missing_config"] === "" )) { + if (!$taskurlvalid && (!isset($data["mumie_missing_config"]) || $data["mumie_missing_config"] === "" )) { $errors["prb_selector_btn"] = get_string('mumie_form_required', 'mod_mumie'); } diff --git a/lib.php b/lib.php index d810d045..911e3037 100644 --- a/lib.php +++ b/lib.php @@ -167,7 +167,8 @@ function mumie_cm_info_view(cm_info $cm) { [ 'courseid' => $mumie->course, 'iteminstance' => $mumie->id, 'itemmodule' => 'mumie', - ]); + ] + ); $info = ''; $duedate = locallib::get_effective_duedate($USER->id, $mumie); @@ -178,16 +179,16 @@ function mumie_cm_info_view(cm_info $cm) { $info .= html_writer::tag('p', $content, ['class' => 'tag-info tag mumie_tag badge badge-info ']); } - if ($gradeitem&&$gradeitem->gradepass > 0) { + if ($gradeitem && $gradeitem->gradepass > 0) { $content = get_string("gradepass", "grades") . ': ' . round($gradeitem->gradepass, 1); $info .= html_writer::tag('p', $content, ['class' => 'tag-info tag mumie_tag badge badge-info ']); } if (!isset($mumie->privategradepool)) { $info .= html_writer::tag( - 'p', - get_string('mumie_tag_disabled', 'mod_mumie'), - ['class' => 'tag-warning tag mumie_tag badge badge-warning'] - ) + 'p', + get_string('mumie_tag_disabled', 'mod_mumie'), + ['class' => 'tag-warning tag mumie_tag badge badge-warning'] + ) . html_writer::tag( 'span', get_string('mumie_tag_disabled_help', 'mod_mumie') @@ -470,12 +471,13 @@ function mod_mumie_core_calendar_is_event_visible(calendar_event $event) { function mumie_update_multiple_tasks($mumie) { global $DB; - if (property_exists($mumie, 'mumie_selected_task_properties') - &&property_exists($mumie, 'mumie_selected_tasks')) { - + if ( + property_exists($mumie, 'mumie_selected_task_properties') + && property_exists($mumie, 'mumie_selected_tasks') + ) { $selectedproperties = json_decode($mumie->mumie_selected_task_properties); $selectedtasks = json_decode($mumie->mumie_selected_tasks); - if (!empty($selectedproperties)&&!empty($selectedtasks)) { + if (!empty($selectedproperties) && !empty($selectedtasks)) { foreach ($selectedtasks as $taskid) { $record = $DB->get_record("mumie", ["id" => $taskid]); foreach ($selectedproperties as $property) { diff --git a/locallib.php b/locallib.php index ca618b95..c64cbbc4 100644 --- a/locallib.php +++ b/locallib.php @@ -45,7 +45,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class locallib { - /** * Get instance of mumie task with its id * @param int $id id of the mumie task diff --git a/mod_form.php b/mod_form.php index 47488f6b..d05b9792 100644 --- a/mod_form.php +++ b/mod_form.php @@ -41,7 +41,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class mod_mumie_mod_form extends moodleform_mod { - /** All valid MUMIE servers (including course structure) available. * @var array */ @@ -146,7 +145,9 @@ private function add_general_fields(MoodleQuickForm $mform, $serveroptions): voi get_string( "mumie_multi_problem_selector", "mod_mumie", - $wiki)); + $wiki + ) + ); $mform->addElement('button', 'multi_problem_selector_btn', get_string('mumie_form_multi_prb_selector_btn', 'mod_mumie')); $launchoptions = []; @@ -360,11 +361,11 @@ private function add_property_selection(): void { 'html', '
' . get_string('mumie_form_task_properties_selection_info', 'mod_mumie') - .'
' - .'
' + . '
' + . '
' . $htmltable - . '
' ); - + . '' + ); } /** @@ -380,7 +381,7 @@ private function add_task_selection(): void { $modules = get_all_instances_in_course("mumie", $COURSE); if (!is_null($cm)) { - $modules = array_filter($modules, function($elem) use($cm){ + $modules = array_filter($modules, function ($elem) use ($cm) { return !($elem->id === $cm->instance); }); } @@ -388,7 +389,7 @@ private function add_task_selection(): void { if (count($modules) < 1) { $notfound = html_writer::tag( 'i', - "- " . get_string("mumie_no_other_task_found", "mod_mumie") ." -", + "- " . get_string("mumie_no_other_task_found", "mod_mumie") . " -", ["style" => "margin-left: 10px;"] ); $mform->addElement( @@ -396,7 +397,8 @@ private function add_task_selection(): void { get_string('mumie_form_tasks_selection_info', 'mod_mumie') . '
' . $notfound - . '
' ); + . '' + ); return; } @@ -404,7 +406,7 @@ private function add_task_selection(): void { foreach ($modules as $module) { $section = $module->section; if (!array_key_exists($section, $tables)) { - $table = new \html_table; + $table = new \html_table(); $table->attributes['class'] = 'generaltable mumie_table'; $table->head = [ get_string( @@ -429,7 +431,8 @@ private function add_task_selection(): void { '', [ "section" => $section, - ]); + ] + ); $table->data[] = [$module->name, $checkboxhtml]; } @@ -441,9 +444,10 @@ private function add_task_selection(): void { $mform->addElement( 'html', get_string('mumie_form_tasks_selection_info', 'mod_mumie') - .'
' + . '
' . $htmltables - . '
' ); + . '
' + ); } /** @@ -641,8 +645,8 @@ private function get_valid_servers_with_structure(): array { \core\notification::warning(get_string( 'mumie_form_no_course_on_server', 'mod_mumie', - $server->get_name()) - ); + $server->get_name() + )); } else { array_push($validservers, $server); } diff --git a/tests/privacy_provider_test.php b/tests/privacy_provider_test.php index b6048500..93a7d51b 100644 --- a/tests/privacy_provider_test.php +++ b/tests/privacy_provider_test.php @@ -192,7 +192,6 @@ public function test_delete_data_for_all_users_in_context(): void { // The data for m2 should still exist. $this->assertCount(1, $DB->get_records('mumie_duedate', ['mumie' => $m2->id])); - } /** @@ -236,7 +235,6 @@ public function test_delete_data_for_user(): void { $this->assertEmpty( $DB->get_fieldset_select('mumie_duedate', 'userid', 'mumie = ?', [$m2->id]) ); - } /** @@ -318,5 +316,4 @@ protected function add_duedate($mumie, $user) { $duedate->set_duedate(1000); $duedate->upsert(); } - } diff --git a/view.php b/view.php index 45bfdc3e..d0599be8 100644 --- a/view.php +++ b/view.php @@ -93,7 +93,6 @@ echo $OUTPUT->footer(); } else if ($action == "open") { - if (!isset($mumietask->privategradepool)) { throw new moodle_exception( 'gradepool_decision_pending', @@ -147,8 +146,10 @@ )); $PAGE->navbar->add( get_string("mumie_grading_settings", "mod_mumie"), - new moodle_url("/mod/mumie/view.php", - ["action" => "grading", "id" => $id]) + new moodle_url( + "/mod/mumie/view.php", + ["action" => "grading", "id" => $id] + ) ); $PAGE->navbar->add(get_string("mumie_submissions", "mod_mumie")); From 9758a831f4feed297d889908398a4685ab232f6b Mon Sep 17 00:00:00 2001 From: Lyannic Date: Fri, 16 Jan 2026 19:12:23 +0100 Subject: [PATCH 002/101] Improve clarity of language strings in English and German translations --- lang/de/mumie.php | 12 ++++++------ lang/en/mumie.php | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lang/de/mumie.php b/lang/de/mumie.php index e9b15eba..74316374 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -24,7 +24,7 @@ */ defined('MOODLE_INTERNAL') || die; -$string['completionpass'] = ' Bewertung für Bestehen notwendig'; +$string['completionpass'] = 'Bewertung für Bestehen notwendig'; $string['completionpass_help'] = 'Wenn diese Option aktiviert ist, wird die Aktivität als abgeschlossen betrachtet, sobald eine Bewertung vorliegt. Icons für die erfolgreiche oder erfolglose Bearbeitung können angezeigt werden, wenn dafür eine Bewertungsgrenze festgelegt wurde.

Bitte beachten Sie:
@@ -37,7 +37,7 @@ $string['gradetopassnotset'] = 'Dieser Test hat keine Bestehensgrenze.'; $string['modulename'] = 'MUMIE Task'; $string['modulename_help'] = '

Dieses Aktivität-Modul ermöglicht die Nutzung von Inhalten der MUMIE-Plattform auf Moodle und eine automatische Synchronisierung der dort erzielten Noten. -Ein MUMIE Task steht hierbei für eine einzelne benote Aufgabe eines MUMIE-Kurses.

+Ein MUMIE Task steht hierbei für eine einzelne benotete Aufgabe eines MUMIE-Kurses.

Was ist MUMIE?

@@ -68,12 +68,12 @@ $string['mumie_calendar_duedate_extension'] = 'Verlängerte Abgabefrist: {$a}'; $string['mumie_calendar_duedate_name'] = 'Abgabefirst: {$a}'; $string['mumie_due_date'] = 'Abgabefrist'; -$string['mumie_due_date_help'] = 'Die Noten werden erst nach Ablauf der Frist mit Moodle synchronisiert.'; +$string['mumie_due_date_help'] = 'Noten, die nach der ausgewählten Frist erzielt wurden, werden nicht mit Moodle synchronisiert.'; $string['mumie_duedate_extension'] = 'Abfabefristverlängerung'; $string['mumie_duedate_form'] = 'Abgabefrist verlängern'; $string['mumie_duedate_not_set'] = 'Keine allgemeine Abgabefrist für diese MUMIE-Task festgelegt!'; $string['mumie_duration_selector'] = 'Bearbeitungszeitraum'; -$string['mumie_duration_selector_help'] = 'Bei einem begrenzten Bearbeitungszeitraum werden die Noten erst nach Ablauf der Fristen mit Moodle synchronisiert.'; +$string['mumie_duration_selector_help'] = 'Bei einem begrenzten Bearbeitungszeitraum werden nur die in diesem Zeitraum erzielten Noten mit Moodle synchronisiert.'; $string['mumie_form_activity_container'] = 'Startcontainer'; $string['mumie_form_activity_container_embedded'] = 'Eingebunden'; $string['mumie_form_activity_container_help'] = 'Bitte wählen Sie, ob diese Aktivität in die Moodle-Umgebung eingebunden oder in einem neuen Browser-Tab geöffnet werden soll.

Bitte beachten Sie, dass eingebettete MUMIE Tasks aus technischen Gründen nicht mit Safari bearbeitet werden können. Für diese User wird diese MUMIE Task daher im gesamten Tab dargestellt.'; @@ -142,9 +142,9 @@ $string['mumie_task_updated'] = 'Es wurde eine weitere MUMIE-Task aktualisiert'; $string['mumie_tasks_updated'] = 'Es wurden {$a} weitere MUMIE-Tasks aktualisiert'; $string['mumie_timelimit'] = 'Zeitlimit'; -$string['mumie_timelimit_help'] = 'Die Note eines Studierenden wird erst mit Moodle synchronisiert, nachdem seine individuelle Frist abgelaufen ist. Das Zeitlimit beginnt in dem Moment, in dem ein Studierender eine MUMIE-Aufgabe zum ersten Mal öffnet.'; +$string['mumie_timelimit_help'] = 'Noten, die nach Ablauf des Zeitlimits erzielt wurden, werden nicht mit Moodle synchronisiert. Das Zeitlimit beginnt in dem Moment, in dem ein Studierender eine MUMIE-Aufgabe zum ersten Mal öffnet.'; $string['mumie_unlimited'] = 'Uneingeschränkt'; -$string['mumie_unlimited_help'] = 'Die Noten können zu jeder Zeit mit Moodle synchronisiert werden.'; +$string['mumie_unlimited_help'] = 'Es gibt keine zeitliche Beschränkung. Alle erzielten Noten werden mit Moodle synchronisiert.'; $string['mumieintro'] = 'Aktivitätsbeschreibung'; $string['name'] = 'Name'; $string['nomumieinstance'] = 'In diesem Kurs gibt es keine MUMIE-Instanzen'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index ac863de7..518b89d6 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -60,7 +60,7 @@ $string['mumie_duedate_form'] = 'Grant a due date extension'; $string['mumie_duedate_not_set'] = 'No general due date set for this MUMIE Task!'; $string['mumie_duration_selector'] = 'Working period'; -$string['mumie_duration_selector_help'] = 'If the working period is limited, grades are only synchronized with Moodle after the period ends.'; +$string['mumie_duration_selector_help'] = 'If the working period is limited, only grades achieved within that period are synchronized with Moodle.'; $string['mumie_form_activity_container'] = 'Launch container'; $string['mumie_form_activity_container_embedded'] = 'embedded'; $string['mumie_form_activity_container_help'] = 'Please select whether the activity should be opened in a new browser tab or embedded into moodle.

Please note that embedded MUMIE Tasks cannot be opened with Safari due to technical limitations. This MUMIE Task will be opened in a tab instead for Safari users'; @@ -139,9 +139,9 @@ $string['mumie_task_updated'] = 'One additional MUMIE Task has been updated'; $string['mumie_tasks_updated'] = '{$a} additional MUMIE Tasks have been updated'; $string['mumie_timelimit'] = 'Timelimit'; -$string['mumie_timelimit_help'] = 'Each student\'s grade is only synchronized with Moodle after their individual deadline has passed. The timelimit will start the moment a student first opens a MUMIE task.'; +$string['mumie_timelimit_help'] = 'Grades that were earned after the time limit will not be synchronized with Moodle. The time limit will start the moment a student first opens a MUMIE task.'; $string['mumie_unlimited'] = 'Unlimited'; -$string['mumie_unlimited_help'] = 'Grades can be synchronized with Moodle at any time.'; +$string['mumie_unlimited_help'] = 'There is no time-based restriction. All achieved grades will be synchronized with Moodle.'; $string['mumie_url_prefix'] = 'MUMIE URL Prefix'; $string['mumie_url_prefix_help'] = 'Specify the MUMIE URL prefix

e.g. https://www.ombplus.de/ombplus

There can only be a single configuration for any URL prefix.'; $string['mumieintro'] = 'Activity description'; From 774341a0bbce1f14101f4ccfd4e9ae52cc2ab0ba Mon Sep 17 00:00:00 2001 From: Lyannic Date: Mon, 15 Dec 2025 16:35:33 +0100 Subject: [PATCH 003/101] Properly define durationController as IIFE singleton --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index cf6efb47..1472bf79 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()}))},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}},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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController().setGradedElemValue(isGraded),function(){const disabled=durationController().isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController().setDurationElements()}()},getGradingType:function(){const isGraded=durationController().getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController().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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()}))},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 5c5d82b9..9ae961ac 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n });\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController().isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController().setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController().setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController().getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController().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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","MumieServer"],"mappings":"AAAAA,4BAAO,CAAC,SAAU,iBAAkB,qBAAsB,iCAAkC,cACxF,iBACUC,gBAAkBC,SAASC,eAAe,wBAC1CC,cAAgBF,SAASG,kBAAkB,wBAAwB,OACrEC,eACAC,eACAC,gBAGEC,mBAAsB,iBAElBC,iBAAmBR,SAASC,eAAe,wBAC3CQ,WAAaT,SAASC,eAAe,8BAKlCS,mBACuB,MAArBD,WAAWE,eAMbC,yBACYF,cAEbF,iBAAiBK,aAAa,WAAY,YAC1CL,iBAAiBG,MAAQ,aAEzBH,iBAAiBM,gBAAgB,YAKN,cAA3BN,iBAAiBG,OACjBX,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,sBAAsBc,MAAMC,QALpC,OAMhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QANzC,OAOhBhB,SAASC,eAAe,oBAAoBc,MAAMC,QAPlC,OAQhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QARvC,QASkB,YAA3BR,iBAAiBG,OACxBX,SAASC,eAAe,oBAAoBc,MAAMC,QAAU,GAC5DhB,SAASC,eAAe,yBAAyBc,MAAMC,QAAU,GAEjEhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAbzC,OAchBhB,SAASC,eAAe,sBAAsBc,MAAMC,QAdpC,OAehBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAfzC,QAgBkB,cAA3BR,iBAAiBG,QACxBX,SAASC,eAAe,sBAAsBc,MAAMC,QAAU,GAC9DhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,oBAAoBc,MAAMC,QApBlC,OAqBhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QArBvC,OAsBhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAtBzC,cA0BjB,CACHC,KAAM,WACFT,iBAAiBU,SAAW,WACxBN,0BAEJO,OAAOC,iBAAiB,QAAQ,KAC5BR,6BAGRS,oBAAqBT,uBACrBF,WAAYA,WACZY,mBAAoB,SAASC,UACzBd,WAAWE,MAAQY,SAAW,IAAM,KAExCC,mBAAoB,kBACTf,WAAWE,SAKxBc,iBAAoB,eAClBC,sBACEC,eAAiB3B,SAASC,eAAe,mBAExC,CACHgB,KAAM,SAASW,WACXF,gBAAkBE,WAEtBC,kBAAmB,iBACTC,mBAAqBH,eAAeI,QAAQJ,eAAeK,eAAeC,YACzEP,gBAAgBQ,MAAKC,QAAUA,OAAOC,OAASN,sBAE1DO,QAAS,WACLV,eAAeW,UAAW,WA4dZC,WACfA,KAAKC,YACRD,KAAKE,YAAYF,KAAKC,YA7dlBE,CAAiBf,kBAdH,GAmBpBgB,0BAA6B,iBACzBC,sBAAwB5C,SAASC,eAAe,uBAChD4C,2BAA6B7C,SAASC,eAAe,qCACvD6C,4BACEC,SAAW/C,SAASG,kBAAkB,aAAa,GAAGQ,eAQnDqC,aAAaC,UACbH,uBAGLA,sBAAsBI,YAAYC,KAAKC,UAAUH,UAAW7C,yBAOvDiD,kBAAYC,+DAAU,GAC3BN,aAAa,CACTO,SAAS,EACTD,QAASA,mBAkBRE,qBACLrC,OAAOC,iBAAiB,WAAYqC,oCAC5BA,MAAMC,SAAWtD,4BAGfuD,UAAYR,KAAKS,MAAMH,MAAMI,MAC7BtC,UAAkC,IAAvBoC,UAAUpC,SACrBuC,uCAAYH,UAAUG,+DAAa,SAErCC,iBAAiBC,UAAUL,UAAUM,oBACrCC,eAAeC,YAAYR,UAAUS,UACrCC,eAAeC,aAAaX,UAAUY,KAAMZ,UAAUS,SAAUT,UAAUvB,MAC1EiC,eAAeG,YAAYjD,UAC3BkD,oBAAoBC,aAAaZ,WACjCT,cACAlC,OAAOwD,QAYfC,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN,+BACPC,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzB7B,QAAS4B,EAAE,GACXE,KAAM,YAEXC,KAAKP,aAAaQ,cAnBnB,MAAOC,mBA1BbvC,aAAa,CACTO,SAAS,EACTD,+DAHuB,KA4BnBkC,CAAYD,MAAMjC,aAEvB,YAwBEmC,iBACCC,YAAcrB,eAAesB,iBAC7BC,UAAYvB,eAAewB,yBAC3BC,eAAiBrE,iBAAiBI,oBAAoBkE,cAwCtBC,yBAAAA,kBAvCMF,eAwCrC,IAAIG,IAxCiB7F,gBAwCOsD,SAAW,IAAIuC,IAAID,mBAAmBtC,QAtC9D,wCAEHX,SACA,cACAmD,mBAAmBJ,gBACnB,gBACA5B,eAAeiC,sBACf,WAAaD,mBAAmB/E,OAAOiF,SAAS1C,QAChD,gBAAkBgC,YAClB,cAAgBpF,WACfsF,UAAY,cAAgBA,UAAY,IAE1CxF,eAAAA,6BAGH2C,SACA,cACAmD,mBAAmBJ,gBACnB,gBACA5B,eAAeiC,sBACf,WAAaD,mBAAmB/E,OAAOiF,SAAS1C,QAChD,WAAarD,eACb,gBAAkBqF,YAVftF,oCAaFwF,UAAY,cAAgBA,UAAY,UAgB1C,CACH3E,KAAM,WACF2B,sBAAsByD,QAAU,WAC5BvD,sBAAwB3B,OAAOmF,KAAKb,WAAY,WAGpDtE,OAAOoF,QAAU,WACblD,eAGJlC,OAAOC,iBAAiB,gBAAgB,WACpCiC,iBACD,GAEHG,qBAEAX,2BAA2BwD,QAAU,SAASG,GAC1CA,EAAEC,iBACF3D,sBAAwB3B,OAAOmF,KAC3BlG,eAAAA,mCAGA8F,mBAAmBzE,iBAAiBI,oBAAoBkE,WACxD,mBACA,SACA,oCAIZ1D,QAAS,WACLO,sBAAsBN,UAAW,IArKV,GA0K7ByB,iBAAoB,iBAChB2C,eAAiB1G,SAASC,eAAe,mBACzC0G,eAAiB3G,SAASG,kBAAkB,oBAAoB,YAgB7DyG,mDACCC,eAAiB9C,iBAAiB+C,oBAClCC,iBAAmB7C,eAAeiC,sBACnCU,gBAAmBE,mBAGxBL,eAAe/F,oCAAQkG,eAAezE,KACjCF,MAAK8E,aAAeA,YAAY5C,WAAa2C,2DAD3BE,sBAC8CtG,aAGlE,CACHM,KAAM,WACF2F,oBAEJE,kBAAmB,kBACCrF,iBAAiBI,oBAAoBqF,QACtChF,MAAKiF,QAAUA,OAAOC,aAAeT,eAAehG,SAEvEqD,UAAW,SAASqD,gBA1BMD,WAAAA,WA2BDC,WA1BzBV,eAAehG,MAAQyG,WACvBR,qBAZkB,GA0CpB1C,eAAkB,iBACdoD,aAAetH,SAASC,eAAe,qBACtC,CACHkG,oBAAqB,kBACVmB,aAAa3G,OAExBwD,YAAa,SAASoD,MAClBD,aAAa3G,MAAQ4G,OAPT,GAYlBlD,eAAkB,iBACdmD,mBAAqBxH,SAASG,kBAAkB,WAAW,GAC3DsH,SAAWzH,SAASC,eAAe,WACnCyH,mBAAqB1H,SAASC,eAAe,oCAc1C0H,yBAAyBC,eAC9BF,mBAAmB/G,MAAQiH,uBAQtBC,cAActD,KAAMH,gBACnBwD,uBAWYrD,KAAMH,iBACjBG,KAnCuB,SAmCYH,SAZpB0D,CAAavD,KAAMH,UACzCoD,mBAAmB7G,MAAQiH,cAC3BD,yBAAyBC,qBAoCtB,CACH3G,KAAM,WACF0G,yBAAyBH,mBAAmB7G,QAEhD2D,aAAc,SAASC,KAAMH,SAAUhC,MACnCyF,cAActD,KAAMH,mBA5DRhC,MAChBqF,SAAS9G,MAAQyB,KA4Db2F,CAAW3F,OAEfoC,YAAa,SAASjD,UAClBhB,qBAAqBe,mBAAmBC,2BAhBtCe,SAAW/B,qBAAqBG,aACtCV,SAASC,eAAe,aAAaqC,SAAWA,SAChDtC,SAASC,eAAe,gBAAgBqC,SAAWA,SACnDtC,SAASC,eAAe,eAAeqC,SAAWA,SAClD/B,qBAAqBc,sBAajB2G,IAEJrC,eAAgB,iBACNpE,SAAWhB,qBAAqBiB,2BACrB,MAAbD,SACO,SACa,MAAbA,SACA,WAEJ,OAEXsE,uBAAwB,kBAvCJtB,KAwCMiD,mBAAmB7G,OAvCpCsH,SA5CqB,UA6CnB1D,KAAK2D,MA7Cc,UA6CmB,GAE1C3D,SAJaA,OA/CJ,GA6FlB4D,wBAA2B,iBACvBC,wBAA0BpI,SAASG,kBAAkB,6BACrDkI,uBAAyBrI,SAASG,kBAAkB,kCAAkC,OACxFmI,iBAAmB,SACjBC,oBAAsBvI,SAASG,kBAAkB,yBACjDqI,cAAgBxI,SAASG,kBAAkB,wBAAwB,OACrEsI,gBAAkB,SAChBC,cAAgB1I,SAASG,kBAAkB,kCAwE1C,CACHc,KAAM,WAvDNsH,oBAAoBI,SAAQ,SAASC,UACjCA,SAAS1H,SAAW,WACX0H,SAASC,QAGVJ,gBAAgBK,KAAKF,SAASjI,OAF9B8H,gBAAkBA,gBAAgBM,QAAOxG,MAAQA,OAASqG,SAASjI,QAIvE6H,cAAc7H,MAAQwC,KAAKC,UAAUqF,qBAS7CL,wBAAwBO,SAAQ,SAASC,UACrCA,SAAS1H,SAAW,WACX0H,SAASC,QAGVP,iBAAiBQ,KAAKF,SAASjI,OAF/B2H,iBAAmBA,iBAAiBS,QAAOxG,MAAQA,OAASqG,SAASjI,QAIzE0H,uBAAuB1H,MAAQwC,KAAKC,UAAUkF,sBAStDI,cAAcC,SAAQ,SAASK,iBAC3BA,gBAAgB9H,SAAW,WAClB8H,gBAAgBH,QAQjBN,oBAAoBI,SAAQ,SAASM,kBApD5BC,MAAOC,QAqDRF,aAAaG,aAAa,aAAeJ,gBAAgBrI,QACzDsI,aAAaJ,SAAU,EAtDtBK,MAuDeT,gBAvDRU,QAuDyBF,aAAatI,MAtD7DuI,MAAMjB,SAASkB,UAChBD,MAAMJ,KAAKK,aA2CHZ,oBAAoBI,SAAQ,SAASM,cAC7BA,aAAaG,aAAa,aAAeJ,gBAAgBrI,QACzDsI,aAAaJ,SAAU,EACvBJ,gBAAkBA,gBAAgBM,QAAOxG,MAAQ0G,aAAatI,QAAU4B,WAWpFiG,cAAc7H,MAAQwC,KAAKC,UAAUqF,uBA1EpB,GAwF3BhE,oBAAuB,iBACnB4E,iBAAmBrJ,SAASC,eAAe,4BAC1C,CACHyE,aAAc,SAASZ,WACfA,UACAuF,iBAAiBxI,aAAa,QAASsC,KAAKC,UAAUU,YAEtDuF,iBAAiBvI,gBAAgB,WAPpB,YAiBpBwI,qBAAqBC,UAC1B3E,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACNwE,SACPvE,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzB7B,QAAS4B,EAAE,GAAK,MAAQhF,cAAckJ,aAAa,SAAW,OAC9DhE,KAAM,eAEXC,KAAKP,aAAaQ,cAEzB7D,iBAAiBY,UACjBM,0BAA0BN,gBAGvB,CACHpB,KAAM,SAASuI,eAAgBC,eAAgBlC,MAC3CnH,eAAiBqJ,eACjBpJ,eAAiBkH,KACjBjH,UAAYkJ,qBACNE,OAAS1J,SAASC,eAAe,WAAWmJ,aAAa,SACzD1H,gBAAkByB,KAAKS,MAAM5D,SAASG,kBAAkB,0BAA0B,GAAGQ,OACvF+I,QAoC+E,KAAhF1J,SAASG,kBAAkB,wBAAwB,GAAGiJ,aAAa,SAnClEE,qBAAqB,6BACb5H,gBAAgBiI,QAGxBlI,iBAAiBR,KAAKS,iBACtBqC,iBAAiB9C,OACjBoD,eAAepD,OACfkH,wBAAwBlH,OACxB0B,0BAA0B1B,OAC1BV,qBAAqBU,QAPrBqI,qBAAqB,6BASzBnB,wBAAwBlH,OACpBlB,iBACA6E,QAAQ,CAAC,mCAAmC,SAASgF,aACjDA,YAAY3I,KAAKlB,gBAAiBO"} \ 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 041124cc..3db9dcce 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -75,7 +75,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv return gradedElem.value; } }; - }); + })(); const serverController = (function() { let serverStructure; @@ -378,11 +378,11 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv * Form inputs related to grades should be disabled if the MUMIE Task is not graded. */ function updateGradeEditability() { - const disabled = durationController().isUngraded(); + const disabled = durationController.isUngraded(); document.getElementById('id_points').disabled = disabled; document.getElementById('id_gradepass').disabled = disabled; document.getElementById('id_gradecat').disabled = disabled; - durationController().setDurationElements(); + durationController.setDurationElements(); } return { @@ -394,11 +394,11 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv updateName(name); }, setIsGraded: function(isGraded) { - durationController().setGradedElemValue(isGraded); + durationController.setGradedElemValue(isGraded); updateGradeEditability(); }, getGradingType: function() { - const isGraded = durationController().getGradedElemValue(); + const isGraded = durationController.getGradedElemValue(); if (isGraded === '1') { return 'graded'; } else if (isGraded === '0') { @@ -551,7 +551,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv taskController.init(); multiTaskEditController.init(); problemSelectorController.init(); - durationController().init(); + durationController.init(); } multiTaskEditController.init(); if (addServerButton) { From bb530049454b6c15c375901be91b1800f731575a Mon Sep 17 00:00:00 2001 From: Lyannic Date: Mon, 15 Dec 2025 17:28:00 +0100 Subject: [PATCH 004/101] Temporarily log updateDurationElements --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 1472bf79..b176094e 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()}))},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){console.log("gradedElem.value",null==gradedElem?void 0:gradedElem.value,"disabled?",isUngraded());isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()}))},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 9ae961ac..8577a681 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n console.log('gradedElem.value', gradedElem?.value, 'disabled?', isUngraded());\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","console","log","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 3db9dcce..90094b5a 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -23,6 +23,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv * Updates the visibility of elements around duration selector. */ function updateDurationElements() { + console.log('gradedElem.value', gradedElem?.value, 'disabled?', isUngraded()); const disabled = isUngraded(); if (disabled) { durationSelector.setAttribute('disabled', 'disabled'); From dedae6c395d3779033399aff5de331a8fd49b9e0 Mon Sep 17 00:00:00 2001 From: Lyannic Date: Mon, 15 Dec 2025 17:49:20 +0100 Subject: [PATCH 005/101] Call updateDurationElements on init --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index b176094e..067a6f2b 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){console.log("gradedElem.value",null==gradedElem?void 0:gradedElem.value,"disabled?",isUngraded());isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()}))},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){console.log("gradedElem.value",null==gradedElem?void 0:gradedElem.value,"disabled?",isUngraded());isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 8577a681..8b5a8f26 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n console.log('gradedElem.value', gradedElem?.value, 'disabled?', isUngraded());\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","console","log","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n console.log('gradedElem.value', gradedElem?.value, 'disabled?', isUngraded());\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","console","log","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 90094b5a..820486a3 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -66,6 +66,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv window.addEventListener("load", () => { updateDurationElements(); }); + updateDurationElements(); }, setDurationElements: updateDurationElements, isUngraded: isUngraded, From bfbc03d4d8f4f022c4e4c269c83a65eab61f5e30 Mon Sep 17 00:00:00 2001 From: Lyannic Date: Mon, 15 Dec 2025 18:06:41 +0100 Subject: [PATCH 006/101] Remove log statement used for debugging --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 067a6f2b..90c6e116 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){console.log("gradedElem.value",null==gradedElem?void 0:gradedElem.value,"disabled?",isUngraded());isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 8b5a8f26..8f31bada 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n console.log('gradedElem.value', gradedElem?.value, 'disabled?', isUngraded());\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","console","log","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 820486a3..c7ba5436 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -23,7 +23,6 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv * Updates the visibility of elements around duration selector. */ function updateDurationElements() { - console.log('gradedElem.value', gradedElem?.value, 'disabled?', isUngraded()); const disabled = isUngraded(); if (disabled) { durationSelector.setAttribute('disabled', 'disabled'); From 934b39e21630d10a4a951efc321bad0fd1ebc390 Mon Sep 17 00:00:00 2001 From: Lyannic Date: Mon, 19 Jan 2026 18:29:57 +0100 Subject: [PATCH 007/101] Run tests for Moodle 5.1 in pipeline --- .github/workflows/main.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dcff5409..7a97fc08 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,9 +49,13 @@ jobs: database: 'mysqli' db-version: '8.4' - php: '8.4' - moodle-branch: 'v5.0.1' + moodle-branch: 'MOODLE_501_STABLE' database: 'pgsql' db-version: '15' + - php: '8.4' + moodle-branch: 'MOODLE_501_STABLE' + database: 'mysqli' + db-version: '8.4' services: postgres: From dcf8d44597c53f4cf0ca04055a9a3c31d0eb93b0 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 8 May 2026 15:27:42 +0200 Subject: [PATCH 008/101] Re-adds duration selector, duedate and timelimit as transferable properties. Fixes missing bundle copy and adds extension cleanup on mode change to prevent stale student deadlines --- lib.php | 4 ++++ locallib.php | 24 ++++++++++++++++++++++++ mod_form.php | 1 + 3 files changed, 29 insertions(+) diff --git a/lib.php b/lib.php index 911e3037..3901ee29 100644 --- a/lib.php +++ b/lib.php @@ -78,6 +78,7 @@ function mumie_update_instance($mumie, $mform) { $grades = locallib::has_problem_changed($mumie) ? "reset" : null; mumie_grade_item_update($mumie, $grades); + locallib::delete_extensions_on_mode_change($mumie); $mumie = locallib::clean_up_duration_values($mumie); $calendarservice = new mumie_calendar_service($mumie); $calendarservice->update(); @@ -478,6 +479,9 @@ function mumie_update_multiple_tasks($mumie) { $selectedproperties = json_decode($mumie->mumie_selected_task_properties); $selectedtasks = json_decode($mumie->mumie_selected_tasks); if (!empty($selectedproperties) && !empty($selectedtasks)) { + if (in_array('duration_selector', $selectedproperties)) { + array_push($selectedproperties, 'duedate', 'timelimit'); + } foreach ($selectedtasks as $taskid) { $record = $DB->get_record("mumie", ["id" => $taskid]); foreach ($selectedproperties as $property) { diff --git a/locallib.php b/locallib.php index c64cbbc4..fbb117f9 100644 --- a/locallib.php +++ b/locallib.php @@ -103,6 +103,30 @@ public static function update_pending_gradepool($mumietask) { } } + /** + * Deletes all per-student due date extensions for a MUMIE task if the working period mode has changed. + * Must be called before clean_up_duration_values() so the old mode can still be read from the DB. + * @param stdClass $mumietask the submitted MUMIE task that is supposed to be updated + * @return void + */ + public static function delete_extensions_on_mode_change(stdClass $mumietask): void { + global $DB, $CFG; + if (!property_exists($mumietask, 'duration_selector') || !isset($mumietask->id)) { + return; + } + $oldrecord = $DB->get_record("mumie", ["id" => $mumietask->id]); + if (!$oldrecord) { + return; + } + $oldmode = $oldrecord->duedate > 0 ? 'duedate' + : ($oldrecord->timelimit > 0 ? 'timelimit' + : 'unlimited'); + if ($oldmode !== $mumietask->duration_selector) { + require_once($CFG->dirroot . "/mod/mumie/classes/mumie_duedate_extension.php"); + mumie_duedate_extension::delete_all_for_mumie($mumietask->id); + } + } + /** * The function is called whenever a MUMIE task is created or updated. * Cleans up the submitted duedate and timelimit if not selected in the duration selector. diff --git a/mod_form.php b/mod_form.php index d05b9792..ec9627e2 100644 --- a/mod_form.php +++ b/mod_form.php @@ -343,6 +343,7 @@ private function add_property_selection(): void { $taskproperties = [ [get_string('mumie_form_activity_container', 'mod_mumie'), "launchcontainer"], [get_string('mumie_form_points', 'mod_mumie'), "points"], + [get_string('mumie_duration_selector', 'mod_mumie'), "duration_selector"], ]; $table = new \html_table(); $table->attributes['class'] = 'generaltable mumie_table'; From 508385ea2df1608461a8f3c0e13ae87b14878c1e Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 12 May 2026 09:25:50 +0200 Subject: [PATCH 009/101] update version --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index d7e9063f..45175157 100644 --- a/version.php +++ b/version.php @@ -25,10 +25,10 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2025070300; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2026051200; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2022112800; // 4.1 LTS -$plugin->release = "v1.9.1"; +$plugin->release = "v1.9.2"; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = [ 'auth_mumie' => 2025051500, From 771705792ec7f12adc829cbd50e368c220c41ef1 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 12 May 2026 11:55:15 +0200 Subject: [PATCH 010/101] remove php form block for due date --- mod_form.php | 1 - 1 file changed, 1 deletion(-) diff --git a/mod_form.php b/mod_form.php index ec9627e2..7eec6d89 100644 --- a/mod_form.php +++ b/mod_form.php @@ -505,7 +505,6 @@ private function set_grade_data($data, $mform): void { } else { $mform->setDefault('duration_selector', 'unlimited'); } - $mform->disabledIf('duration_selector', null); } /** From b4c3ef4bcd6cbbdfb94e3dab963c44da1c34bbe5 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 12 May 2026 15:22:02 +0200 Subject: [PATCH 011/101] activate apply to other mumie task for deadline --- amd/src/mod_form.js | 10 ++++++++++ mod_form.php | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index c7ba5436..e9091fdd 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -55,6 +55,16 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv document.getElementById('fitem_id_duedate_info').style.display = displayNone; document.getElementById('fitem_id_unlimited_info').style.display = displayNone; } + + const durationPropCheckbox = document.getElementById('mumie_duration_property_checkbox'); + if (durationPropCheckbox) { + const show = durationSelector.value === 'duedate'; + durationPropCheckbox.closest('tr').style.display = show ? '' : displayNone; + if (!show && durationPropCheckbox.checked) { + durationPropCheckbox.checked = false; + durationPropCheckbox.dispatchEvent(new Event('change')); + } + } } return { diff --git a/mod_form.php b/mod_form.php index 7eec6d89..cc9bf3fe 100644 --- a/mod_form.php +++ b/mod_form.php @@ -352,7 +352,8 @@ private function add_property_selection(): void { foreach ($taskproperties as $taskproperty) { $label = $taskproperty[0]; $value = $taskproperty[1]; - $checkboxhtml = html_writer::checkbox("mumie_multi_edit_property", $value, false); + $extraattrs = $value === 'duration_selector' ? ['id' => 'mumie_duration_property_checkbox'] : []; + $checkboxhtml = html_writer::checkbox("mumie_multi_edit_property", $value, false, '', $extraattrs); $table->data[] = [$label, $checkboxhtml]; } From ea2e1743e08136d0359ecf3cb2d49d045507bd37 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 12 May 2026 15:47:36 +0200 Subject: [PATCH 012/101] npx uglify --- amd/build/mod_form.min.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 90c6e116..714f1b95 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1,3 +1 @@ -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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 +define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let i=document.getElementById("id_duration_selector"),t=document.getElementById("id_mumie_isgraded");function d(){return"0"===t.value}function e(){d()?(i.setAttribute("disabled","disabled"),i.value="unlimited"):i.removeAttribute("disabled");var e,t="none",n=("unlimited"===i.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t,document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t):"duedate"===i.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=t,document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t):"timelimit"===i.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t,document.getElementById("fitem_id_unlimited_info").style.display=t),document.getElementById("mumie_duration_property_checkbox"));n&&(e="duedate"===i.value,n.closest("tr").style.display=e?"":t,!e)&&n.checked&&(n.checked=!1,n.dispatchEvent(new Event("change")))}return{init:function(){i.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:d,setGradedElemValue:function(e){t.value=e?"1":"0"},getGradedElemValue:function(){return t.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),o=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,o=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function u(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),f.setSelection(t.link,t.language,t.name),f.setIsGraded(e),_.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=f.getGradingType(),i=f.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+o+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+o+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),u(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),f=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function o(e){t.value=e}function u(e,t){t=t;e=e+d+t;o(n.value=e)}return{init:function(){o(n.value)},setSelection:function(e,t,n){u(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),u=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],o=[],u=document.getElementsByName("mumie_multi_edit_section");function l(){u.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=o,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,o=o.filter(e=>t.value!==e))}),d.value=JSON.stringify(o)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?o.push(t.value):o=o.filter(e=>e!==t.value),d.value=JSON.stringify(o)}}),e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i)}}),l()}}})(),_=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),o.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),f.init(),u.init(),o.init(),l.init()):y("mumie_form_no_server_conf"),u.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file From 11dc7198bb7c0c82876e7f33f31498717bbb0f22 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 12 May 2026 15:56:49 +0200 Subject: [PATCH 013/101] fix php form --- amd/build/mod_form.min.js | 2 +- amd/src/mod_form.js | 15 +++++++++------ mod_form.php | 9 ++++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 714f1b95..5a86e327 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let i=document.getElementById("id_duration_selector"),t=document.getElementById("id_mumie_isgraded");function d(){return"0"===t.value}function e(){d()?(i.setAttribute("disabled","disabled"),i.value="unlimited"):i.removeAttribute("disabled");var e,t="none",n=("unlimited"===i.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t,document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t):"duedate"===i.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=t,document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t):"timelimit"===i.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t,document.getElementById("fitem_id_unlimited_info").style.display=t),document.getElementById("mumie_duration_property_checkbox"));n&&(e="duedate"===i.value,n.closest("tr").style.display=e?"":t,!e)&&n.checked&&(n.checked=!1,n.dispatchEvent(new Event("change")))}return{init:function(){i.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:d,setGradedElemValue:function(e){t.value=e?"1":"0"},getGradedElemValue:function(){return t.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),o=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,o=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function u(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),f.setSelection(t.link,t.language,t.name),f.setIsGraded(e),_.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=f.getGradingType(),i=f.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+o+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+o+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),u(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),f=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function o(e){t.value=e}function u(e,t){t=t;e=e+d+t;o(n.value=e)}return{init:function(){o(n.value)},setSelection:function(e,t,n){u(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),u=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],o=[],u=document.getElementsByName("mumie_multi_edit_section");function l(){u.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=o,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,o=o.filter(e=>t.value!==e))}),d.value=JSON.stringify(o)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?o.push(t.value):o=o.filter(e=>e!==t.value),d.value=JSON.stringify(o)}}),e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i)}}),l()}}})(),_=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),o.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),f.init(),u.init(),o.init(),l.init()):y("mumie_form_no_server_conf"),u.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file +define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let i=document.getElementById("id_duration_selector"),t=document.getElementById("id_mumie_isgraded");function d(){return"0"===t.value}function e(){d()?(i.setAttribute("disabled","disabled"),i.value="unlimited"):i.removeAttribute("disabled");var e,t="none",n=("unlimited"===i.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t,document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t):"duedate"===i.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=t,document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t):"timelimit"===i.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t,document.getElementById("fitem_id_unlimited_info").style.display=t),document.getElementById("mumie_duration_property_row"));n&&(e="duedate"===i.value,n.style.display=e?"":t,e||(t=n.querySelector('[name="mumie_multi_edit_property"]'))&&t.checked&&(t.checked=!1,t.dispatchEvent(new Event("change"))))}return{init:function(){i.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:d,setGradedElemValue:function(e){t.value=e?"1":"0"},getGradedElemValue:function(){return t.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),o=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,o=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function u(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),_.setSelection(t.link,t.language,t.name),_.setIsGraded(e),f.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=_.getGradingType(),i=_.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+o+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+o+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),u(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),_=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function o(e){t.value=e}function u(e,t){t=t;e=e+d+t;o(n.value=e)}return{init:function(){o(n.value)},setSelection:function(e,t,n){u(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),u=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],o=[],u=document.getElementsByName("mumie_multi_edit_section");function l(){u.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=o,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,o=o.filter(e=>t.value!==e))}),d.value=JSON.stringify(o)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?o.push(t.value):o=o.filter(e=>e!==t.value),d.value=JSON.stringify(o)}}),e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i)}}),l()}}})(),f=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),o.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),_.init(),u.init(),o.init(),l.init()):y("mumie_form_no_server_conf"),u.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index e9091fdd..a2db468b 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -56,13 +56,16 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv document.getElementById('fitem_id_unlimited_info').style.display = displayNone; } - const durationPropCheckbox = document.getElementById('mumie_duration_property_checkbox'); - if (durationPropCheckbox) { + const durationPropRow = document.getElementById('mumie_duration_property_row'); + if (durationPropRow) { const show = durationSelector.value === 'duedate'; - durationPropCheckbox.closest('tr').style.display = show ? '' : displayNone; - if (!show && durationPropCheckbox.checked) { - durationPropCheckbox.checked = false; - durationPropCheckbox.dispatchEvent(new Event('change')); + durationPropRow.style.display = show ? '' : displayNone; + if (!show) { + const cb = durationPropRow.querySelector('[name="mumie_multi_edit_property"]'); + if (cb && cb.checked) { + cb.checked = false; + cb.dispatchEvent(new Event('change')); + } } } } diff --git a/mod_form.php b/mod_form.php index cc9bf3fe..55a0ac8f 100644 --- a/mod_form.php +++ b/mod_form.php @@ -352,9 +352,12 @@ private function add_property_selection(): void { foreach ($taskproperties as $taskproperty) { $label = $taskproperty[0]; $value = $taskproperty[1]; - $extraattrs = $value === 'duration_selector' ? ['id' => 'mumie_duration_property_checkbox'] : []; - $checkboxhtml = html_writer::checkbox("mumie_multi_edit_property", $value, false, '', $extraattrs); - $table->data[] = [$label, $checkboxhtml]; + $checkboxhtml = html_writer::checkbox("mumie_multi_edit_property", $value, false); + $row = new html_table_row([$label, $checkboxhtml]); + if ($value === 'duration_selector') { + $row->attributes['id'] = 'mumie_duration_property_row'; + } + $table->data[] = $row; } $htmltable = html_writer::table($table); From e5c6e0ce9e5c9fe1c917c55d85acd6d1c4f10093 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 08:44:55 +0200 Subject: [PATCH 014/101] remove useless changes --- amd/build/mod_form.min.js | 2 +- amd/src/mod_form.js | 12 ------------ mod_form.php | 6 +----- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 5a86e327..dacf03af 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let i=document.getElementById("id_duration_selector"),t=document.getElementById("id_mumie_isgraded");function d(){return"0"===t.value}function e(){d()?(i.setAttribute("disabled","disabled"),i.value="unlimited"):i.removeAttribute("disabled");var e,t="none",n=("unlimited"===i.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t,document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t):"duedate"===i.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=t,document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t):"timelimit"===i.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t,document.getElementById("fitem_id_unlimited_info").style.display=t),document.getElementById("mumie_duration_property_row"));n&&(e="duedate"===i.value,n.style.display=e?"":t,e||(t=n.querySelector('[name="mumie_multi_edit_property"]'))&&t.checked&&(t.checked=!1,t.dispatchEvent(new Event("change"))))}return{init:function(){i.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:d,setGradedElemValue:function(e){t.value=e?"1":"0"},getGradedElemValue:function(){return t.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),o=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,o=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function u(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),_.setSelection(t.link,t.language,t.name),_.setIsGraded(e),f.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=_.getGradingType(),i=_.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+o+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+o+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),u(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),_=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function o(e){t.value=e}function u(e,t){t=t;e=e+d+t;o(n.value=e)}return{init:function(){o(n.value)},setSelection:function(e,t,n){u(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),u=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],o=[],u=document.getElementsByName("mumie_multi_edit_section");function l(){u.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=o,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,o=o.filter(e=>t.value!==e))}),d.value=JSON.stringify(o)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?o.push(t.value):o=o.filter(e=>e!==t.value),d.value=JSON.stringify(o)}}),e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i)}}),l()}}})(),f=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),o.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),_.init(),u.init(),o.init(),l.init()):y("mumie_form_no_server_conf"),u.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file +define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let t=document.getElementById("id_duration_selector"),n=document.getElementById("id_mumie_isgraded");function i(){return"0"===n.value}function e(){i()?(t.setAttribute("disabled","disabled"),t.value="unlimited"):t.removeAttribute("disabled");var e="none";"unlimited"===t.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=e,document.getElementById("fitem_id_timelimit_info").style.display=e,document.getElementById("fitem_id_duedate").style.display=e,document.getElementById("fitem_id_duedate_info").style.display=e):"duedate"===t.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=e,document.getElementById("fitem_id_timelimit").style.display=e,document.getElementById("fitem_id_timelimit_info").style.display=e):"timelimit"===t.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=e,document.getElementById("fitem_id_duedate_info").style.display=e,document.getElementById("fitem_id_unlimited_info").style.display=e)}return{init:function(){t.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:i,setGradedElemValue:function(e){n.value=e?"1":"0"},getGradedElemValue:function(){return n.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),o=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,o=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function u(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),f.setSelection(t.link,t.language,t.name),f.setIsGraded(e),_.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=f.getGradingType(),i=f.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+o+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+o+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),u(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),f=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function o(e){t.value=e}function u(e,t){t=t;e=e+d+t;o(n.value=e)}return{init:function(){o(n.value)},setSelection:function(e,t,n){u(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),u=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],o=[],u=document.getElementsByName("mumie_multi_edit_section");function l(){u.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=o,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,o=o.filter(e=>t.value!==e))}),d.value=JSON.stringify(o)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?o.push(t.value):o=o.filter(e=>e!==t.value),d.value=JSON.stringify(o)}}),e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i)}}),l()}}})(),_=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),o.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),f.init(),u.init(),o.init(),l.init()):y("mumie_form_no_server_conf"),u.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index a2db468b..221e001b 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -56,18 +56,6 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv document.getElementById('fitem_id_unlimited_info').style.display = displayNone; } - const durationPropRow = document.getElementById('mumie_duration_property_row'); - if (durationPropRow) { - const show = durationSelector.value === 'duedate'; - durationPropRow.style.display = show ? '' : displayNone; - if (!show) { - const cb = durationPropRow.querySelector('[name="mumie_multi_edit_property"]'); - if (cb && cb.checked) { - cb.checked = false; - cb.dispatchEvent(new Event('change')); - } - } - } } return { diff --git a/mod_form.php b/mod_form.php index 55a0ac8f..7eec6d89 100644 --- a/mod_form.php +++ b/mod_form.php @@ -353,11 +353,7 @@ private function add_property_selection(): void { $label = $taskproperty[0]; $value = $taskproperty[1]; $checkboxhtml = html_writer::checkbox("mumie_multi_edit_property", $value, false); - $row = new html_table_row([$label, $checkboxhtml]); - if ($value === 'duration_selector') { - $row->attributes['id'] = 'mumie_duration_property_row'; - } - $table->data[] = $row; + $table->data[] = [$label, $checkboxhtml]; } $htmltable = html_writer::table($table); From 212af528c0cf3d66a9618de89ecb3d53efef031d Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 09:08:36 +0200 Subject: [PATCH 015/101] test dynamic duedate filed --- amd/build/mod_form.min.js | 2 +- amd/src/mod_form.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index dacf03af..fc103b79 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let t=document.getElementById("id_duration_selector"),n=document.getElementById("id_mumie_isgraded");function i(){return"0"===n.value}function e(){i()?(t.setAttribute("disabled","disabled"),t.value="unlimited"):t.removeAttribute("disabled");var e="none";"unlimited"===t.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=e,document.getElementById("fitem_id_timelimit_info").style.display=e,document.getElementById("fitem_id_duedate").style.display=e,document.getElementById("fitem_id_duedate_info").style.display=e):"duedate"===t.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=e,document.getElementById("fitem_id_timelimit").style.display=e,document.getElementById("fitem_id_timelimit_info").style.display=e):"timelimit"===t.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=e,document.getElementById("fitem_id_duedate_info").style.display=e,document.getElementById("fitem_id_unlimited_info").style.display=e)}return{init:function(){t.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:i,setGradedElemValue:function(e){n.value=e?"1":"0"},getGradedElemValue:function(){return n.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),o=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,o=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function u(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),f.setSelection(t.link,t.language,t.name),f.setIsGraded(e),_.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=f.getGradingType(),i=f.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+o+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+o+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),u(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),f=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function o(e){t.value=e}function u(e,t){t=t;e=e+d+t;o(n.value=e)}return{init:function(){o(n.value)},setSelection:function(e,t,n){u(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),u=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],o=[],u=document.getElementsByName("mumie_multi_edit_section");function l(){u.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=o,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,o=o.filter(e=>t.value!==e))}),d.value=JSON.stringify(o)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?o.push(t.value):o=o.filter(e=>e!==t.value),d.value=JSON.stringify(o)}}),e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i)}}),l()}}})(),_=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),o.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),f.init(),u.init(),o.init(),l.init()):y("mumie_form_no_server_conf"),u.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file +define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let i=document.getElementById("id_duration_selector"),t=document.getElementById("id_mumie_isgraded");function d(){return"0"===t.value}function e(){d()?(i.setAttribute("disabled","disabled"),i.value="unlimited"):i.removeAttribute("disabled");var e,t="none",n=("unlimited"===i.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t,document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t):"duedate"===i.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=t,document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t):"timelimit"===i.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t,document.getElementById("fitem_id_unlimited_info").style.display=t),document.querySelector('[name="mumie_multi_edit_property"][value="duration_selector"]')?.closest("tr"));n&&(e="duedate"===i.value,n.style.display=e?"":t,e||(t=n.querySelector('[name="mumie_multi_edit_property"]'))&&t.checked&&(t.checked=!1,t.dispatchEvent(new Event("change"))))}return{init:function(){i.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:d,setGradedElemValue:function(e){t.value=e?"1":"0"},getGradedElemValue:function(){return t.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),u=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,u=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function o(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),_.setSelection(t.link,t.language,t.name),_.setIsGraded(e),f.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=_.getGradingType(),i=_.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+u+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+u+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),o(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),_=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function u(e){t.value=e}function o(e,t){t=t;e=e+d+t;u(n.value=e)}return{init:function(){u(n.value)},setSelection:function(e,t,n){o(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),o=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],u=[],o=document.getElementsByName("mumie_multi_edit_section");function l(){o.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=u,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,u=u.filter(e=>t.value!==e))}),d.value=JSON.stringify(u)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?u.push(t.value):u=u.filter(e=>e!==t.value),d.value=JSON.stringify(u)}}),e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i)}}),l()}}})(),f=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),u.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),_.init(),o.init(),u.init(),l.init()):y("mumie_form_no_server_conf"),o.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 221e001b..789e5600 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -56,6 +56,20 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv document.getElementById('fitem_id_unlimited_info').style.display = displayNone; } + const durationPropRow = document + .querySelector('[name="mumie_multi_edit_property"][value="duration_selector"]') + ?.closest('tr'); + if (durationPropRow) { + const show = durationSelector.value === 'duedate'; + durationPropRow.style.display = show ? '' : displayNone; + if (!show) { + const cb = durationPropRow.querySelector('[name="mumie_multi_edit_property"]'); + if (cb && cb.checked) { + cb.checked = false; + cb.dispatchEvent(new Event('change')); + } + } + } } return { From 1bb38bcafe56ff905cb47f37548088cc8ab87d49 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 09:25:20 +0200 Subject: [PATCH 016/101] rename deadline filed --- lang/de/mumie.php | 1 + lang/en/mumie.php | 1 + mod_form.php | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 74316374..c42d9792 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -72,6 +72,7 @@ $string['mumie_duedate_extension'] = 'Abfabefristverlängerung'; $string['mumie_duedate_form'] = 'Abgabefrist verlängern'; $string['mumie_duedate_not_set'] = 'Keine allgemeine Abgabefrist für diese MUMIE-Task festgelegt!'; +$string['mumie_duration_property'] = 'Deadline'; $string['mumie_duration_selector'] = 'Bearbeitungszeitraum'; $string['mumie_duration_selector_help'] = 'Bei einem begrenzten Bearbeitungszeitraum werden nur die in diesem Zeitraum erzielten Noten mit Moodle synchronisiert.'; $string['mumie_form_activity_container'] = 'Startcontainer'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 518b89d6..affcf892 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -59,6 +59,7 @@ $string['mumie_duedate_extension'] = 'Due date extension'; $string['mumie_duedate_form'] = 'Grant a due date extension'; $string['mumie_duedate_not_set'] = 'No general due date set for this MUMIE Task!'; +$string['mumie_duration_property'] = 'Deadline'; $string['mumie_duration_selector'] = 'Working period'; $string['mumie_duration_selector_help'] = 'If the working period is limited, only grades achieved within that period are synchronized with Moodle.'; $string['mumie_form_activity_container'] = 'Launch container'; diff --git a/mod_form.php b/mod_form.php index 7eec6d89..99ea4800 100644 --- a/mod_form.php +++ b/mod_form.php @@ -343,7 +343,7 @@ private function add_property_selection(): void { $taskproperties = [ [get_string('mumie_form_activity_container', 'mod_mumie'), "launchcontainer"], [get_string('mumie_form_points', 'mod_mumie'), "points"], - [get_string('mumie_duration_selector', 'mod_mumie'), "duration_selector"], + [get_string('mumie_duration_property', 'mod_mumie'), "duration_selector"], ]; $table = new \html_table(); $table->attributes['class'] = 'generaltable mumie_table'; From 8c89478be5c9e1e7801af5a6b5fb069ba1e7302a Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 10:04:51 +0200 Subject: [PATCH 017/101] add warning text --- lang/de/mumie.php | 1 + lang/en/mumie.php | 1 + mod_form.php | 6 +++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lang/de/mumie.php b/lang/de/mumie.php index c42d9792..3ec07bf9 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -73,6 +73,7 @@ $string['mumie_duedate_form'] = 'Abgabefrist verlängern'; $string['mumie_duedate_not_set'] = 'Keine allgemeine Abgabefrist für diese MUMIE-Task festgelegt!'; $string['mumie_duration_property'] = 'Deadline'; +$string['mumie_duration_property_hint'] = 'Deadline kann nur für Tasks übernommen werden, welche vorher bereits mit dem Working Period Typ \'Deadline\' erstellt wurden.'; $string['mumie_duration_selector'] = 'Bearbeitungszeitraum'; $string['mumie_duration_selector_help'] = 'Bei einem begrenzten Bearbeitungszeitraum werden nur die in diesem Zeitraum erzielten Noten mit Moodle synchronisiert.'; $string['mumie_form_activity_container'] = 'Startcontainer'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index affcf892..1a06dfb2 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -60,6 +60,7 @@ $string['mumie_duedate_form'] = 'Grant a due date extension'; $string['mumie_duedate_not_set'] = 'No general due date set for this MUMIE Task!'; $string['mumie_duration_property'] = 'Deadline'; +$string['mumie_duration_property_hint'] = 'Deadline can only be applied to tasks that were previously created with the Working Period type \'Deadline\'.'; $string['mumie_duration_selector'] = 'Working period'; $string['mumie_duration_selector_help'] = 'If the working period is limited, only grades achieved within that period are synchronized with Moodle.'; $string['mumie_form_activity_container'] = 'Launch container'; diff --git a/mod_form.php b/mod_form.php index 99ea4800..32e9f3dd 100644 --- a/mod_form.php +++ b/mod_form.php @@ -343,7 +343,11 @@ private function add_property_selection(): void { $taskproperties = [ [get_string('mumie_form_activity_container', 'mod_mumie'), "launchcontainer"], [get_string('mumie_form_points', 'mod_mumie'), "points"], - [get_string('mumie_duration_property', 'mod_mumie'), "duration_selector"], + [ + get_string('mumie_duration_property', 'mod_mumie') + . html_writer::tag('small', get_string('mumie_duration_property_hint', 'mod_mumie'), ['class' => 'form-text text-muted']), + "duration_selector", + ], ]; $table = new \html_table(); $table->attributes['class'] = 'generaltable mumie_table'; From 8efcc65e5c3ddd1438e11c9ca2204fa8492ba7b2 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 11:02:45 +0200 Subject: [PATCH 018/101] filter deadline tasks --- lang/de/mumie.php | 1 + lang/en/mumie.php | 1 + mod_form.php | 7 +++++++ 3 files changed, 9 insertions(+) diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 3ec07bf9..54263bff 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -116,6 +116,7 @@ $string['mumie_form_properties'] = 'Eigenschaften'; $string['mumie_form_server_added'] = 'MUMIE-Server wurde hinzugefügt'; $string['mumie_form_task_properties_selection_info'] = 'Wählen Sie die Eigenschaften dieser MUMIE-Task aus, die in anderen MUMIE-Tasks übernommen werden sollen.'; +$string['mumie_form_tasks_deadline_only'] = 'Es werden nur Tasks mit dem Working Period Typ \'Deadline\' angezeigt.'; $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'; $string['mumie_form_tasks_selection_info'] = 'Bestimmen Sie die MUMIE-Tasks, für die die ausgewählten Eigenschaften ebenfalls übernommen werden sollen.'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 1a06dfb2..1cd003eb 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -110,6 +110,7 @@ $string['mumie_form_server_config'] = 'MUMIE server configuration'; $string['mumie_form_server_not_existing'] = 'There is no MUMIE server for this URL'; $string['mumie_form_task_properties_selection_info'] = 'Select the properties of the current MUMIE Task to apply to other MUMIE Tasks.'; +$string['mumie_form_tasks_deadline_only'] = 'Only tasks with Working Period type \'Deadline\' are shown.'; $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.'; $string['mumie_form_tasks_selection_info'] = 'Choose the MUMIE Tasks you want to apply the selected changes to.'; diff --git a/mod_form.php b/mod_form.php index 32e9f3dd..7329ae19 100644 --- a/mod_form.php +++ b/mod_form.php @@ -391,6 +391,10 @@ private function add_task_selection(): void { }); } + $modules = array_filter($modules, function ($elem) { + return $elem->duedate > 0; + }); + if (count($modules) < 1) { $notfound = html_writer::tag( 'i', @@ -449,6 +453,9 @@ private function add_task_selection(): void { $mform->addElement( 'html', get_string('mumie_form_tasks_selection_info', 'mod_mumie') + . '

' + . get_string('mumie_form_tasks_deadline_only', 'mod_mumie') + . '
' . '
' . $htmltables . '
' From 215deb9943c520236876fafaef992fa97d71abb7 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 11:57:03 +0200 Subject: [PATCH 019/101] add individuall wrnings --- lang/de/mumie.php | 1 + lang/en/mumie.php | 1 + mod_form.php | 17 +++++++++-------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 54263bff..bff2547a 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -116,6 +116,7 @@ $string['mumie_form_properties'] = 'Eigenschaften'; $string['mumie_form_server_added'] = 'MUMIE-Server wurde hinzugefügt'; $string['mumie_form_task_properties_selection_info'] = 'Wählen Sie die Eigenschaften dieser MUMIE-Task aus, die in anderen MUMIE-Tasks übernommen werden sollen.'; +$string['mumie_form_task_no_deadline_warning'] = 'Keine Deadline gesetzt'; $string['mumie_form_tasks_deadline_only'] = 'Es werden nur Tasks mit dem Working Period Typ \'Deadline\' angezeigt.'; $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'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 1cd003eb..1be3f8d4 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -110,6 +110,7 @@ $string['mumie_form_server_config'] = 'MUMIE server configuration'; $string['mumie_form_server_not_existing'] = 'There is no MUMIE server for this URL'; $string['mumie_form_task_properties_selection_info'] = 'Select the properties of the current MUMIE Task to apply to other MUMIE Tasks.'; +$string['mumie_form_task_no_deadline_warning'] = 'No deadline set'; $string['mumie_form_tasks_deadline_only'] = 'Only tasks with Working Period type \'Deadline\' are shown.'; $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.'; diff --git a/mod_form.php b/mod_form.php index 7329ae19..27d28219 100644 --- a/mod_form.php +++ b/mod_form.php @@ -391,10 +391,6 @@ private function add_task_selection(): void { }); } - $modules = array_filter($modules, function ($elem) { - return $elem->duedate > 0; - }); - if (count($modules) < 1) { $notfound = html_writer::tag( 'i', @@ -442,7 +438,15 @@ private function add_task_selection(): void { "section" => $section, ] ); - $table->data[] = [$module->name, $checkboxhtml]; + $label = $module->name; + if (!($module->duedate > 0)) { + $label .= html_writer::tag( + 'small', + ' — ' . get_string('mumie_form_task_no_deadline_warning', 'mod_mumie'), + ['class' => 'text-warning'] + ); + } + $table->data[] = [$label, $checkboxhtml]; } $htmltables = ""; @@ -453,9 +457,6 @@ private function add_task_selection(): void { $mform->addElement( 'html', get_string('mumie_form_tasks_selection_info', 'mod_mumie') - . '
' - . get_string('mumie_form_tasks_deadline_only', 'mod_mumie') - . '
' . '
' . $htmltables . '
' From ae1bc8b4870c4237b5b3fe5f046303c3f1083af7 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 12:07:35 +0200 Subject: [PATCH 020/101] change warnig message --- lang/de/mumie.php | 2 +- lang/en/mumie.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/de/mumie.php b/lang/de/mumie.php index bff2547a..f24993a3 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -116,7 +116,7 @@ $string['mumie_form_properties'] = 'Eigenschaften'; $string['mumie_form_server_added'] = 'MUMIE-Server wurde hinzugefügt'; $string['mumie_form_task_properties_selection_info'] = 'Wählen Sie die Eigenschaften dieser MUMIE-Task aus, die in anderen MUMIE-Tasks übernommen werden sollen.'; -$string['mumie_form_task_no_deadline_warning'] = 'Keine Deadline gesetzt'; +$string['mumie_form_task_no_deadline_warning'] = 'Bearbeitungszeitraum: keine Deadline'; $string['mumie_form_tasks_deadline_only'] = 'Es werden nur Tasks mit dem Working Period Typ \'Deadline\' angezeigt.'; $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'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 1be3f8d4..8c5e4547 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -110,7 +110,7 @@ $string['mumie_form_server_config'] = 'MUMIE server configuration'; $string['mumie_form_server_not_existing'] = 'There is no MUMIE server for this URL'; $string['mumie_form_task_properties_selection_info'] = 'Select the properties of the current MUMIE Task to apply to other MUMIE Tasks.'; -$string['mumie_form_task_no_deadline_warning'] = 'No deadline set'; +$string['mumie_form_task_no_deadline_warning'] = 'Working period: not Deadline'; $string['mumie_form_tasks_deadline_only'] = 'Only tasks with Working Period type \'Deadline\' are shown.'; $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.'; From 3e469bcdabe2688b15e5ab79f46ad6304523b093 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 14:11:24 +0200 Subject: [PATCH 021/101] onyl show warning if deadline is selected --- amd/build/mod_form.min.js | 2 +- amd/src/mod_form.js | 9 +++++++++ mod_form.php | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index fc103b79..12f64074 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1 +1 @@ -define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let i=document.getElementById("id_duration_selector"),t=document.getElementById("id_mumie_isgraded");function d(){return"0"===t.value}function e(){d()?(i.setAttribute("disabled","disabled"),i.value="unlimited"):i.removeAttribute("disabled");var e,t="none",n=("unlimited"===i.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t,document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t):"duedate"===i.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=t,document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t):"timelimit"===i.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t,document.getElementById("fitem_id_unlimited_info").style.display=t),document.querySelector('[name="mumie_multi_edit_property"][value="duration_selector"]')?.closest("tr"));n&&(e="duedate"===i.value,n.style.display=e?"":t,e||(t=n.querySelector('[name="mumie_multi_edit_property"]'))&&t.checked&&(t.checked=!1,t.dispatchEvent(new Event("change"))))}return{init:function(){i.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:d,setGradedElemValue:function(e){t.value=e?"1":"0"},getGradedElemValue:function(){return t.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),u=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,u=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function o(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),_.setSelection(t.link,t.language,t.name),_.setIsGraded(e),f.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=_.getGradingType(),i=_.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+u+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+u+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),o(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),_=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function u(e){t.value=e}function o(e,t){t=t;e=e+d+t;u(n.value=e)}return{init:function(){u(n.value)},setSelection:function(e,t,n){o(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),o=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],u=[],o=document.getElementsByName("mumie_multi_edit_section");function l(){o.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=u,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,u=u.filter(e=>t.value!==e))}),d.value=JSON.stringify(u)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?u.push(t.value):u=u.filter(e=>e!==t.value),d.value=JSON.stringify(u)}}),e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i)}}),l()}}})(),f=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),u.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),_.init(),o.init(),u.init(),l.init()):y("mumie_form_no_server_conf"),o.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file +define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let i=document.getElementById("id_duration_selector"),t=document.getElementById("id_mumie_isgraded");function d(){return"0"===t.value}function e(){d()?(i.setAttribute("disabled","disabled"),i.value="unlimited"):i.removeAttribute("disabled");var e,t="none",n=("unlimited"===i.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t,document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t):"duedate"===i.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=t,document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t):"timelimit"===i.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t,document.getElementById("fitem_id_unlimited_info").style.display=t),document.querySelector('[name="mumie_multi_edit_property"][value="duration_selector"]')?.closest("tr"));n&&(e="duedate"===i.value,n.style.display=e?"":t,e||(t=n.querySelector('[name="mumie_multi_edit_property"]'))&&t.checked&&(t.checked=!1,t.dispatchEvent(new Event("change"))))}return{init:function(){i.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:d,setGradedElemValue:function(e){t.value=e?"1":"0"},getGradedElemValue:function(){return t.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),o=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,o=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function u(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),f.setSelection(t.link,t.language,t.name),f.setIsGraded(e),_.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=f.getGradingType(),i=f.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+o+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+o+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),u(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),f=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function o(e){t.value=e}function u(e,t){t=t;e=e+d+t;o(n.value=e)}return{init:function(){o(n.value)},setSelection:function(e,t,n){u(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),u=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],o=[],u=document.getElementsByName("mumie_multi_edit_section");function l(){e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i);{let t=Array.from(e).some(e=>"duration_selector"===e.value&&e.checked);document.querySelectorAll(".mumie-no-deadline-warning").forEach(function(e){e.style.display=t?"":"none"})}}})}function m(){u.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=o,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,o=o.filter(e=>t.value!==e))}),d.value=JSON.stringify(o)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?o.push(t.value):o=o.filter(e=>e!==t.value),d.value=JSON.stringify(o)}}),l(),m()}}})(),_=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),o.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),f.init(),u.init(),o.init(),l.init()):y("mumie_form_no_server_conf"),u.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 789e5600..3298716f 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -469,6 +469,14 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv /** * Set selection listeners for properties to apply to MUMIE Tasks in the course. */ + function updateNoDeadlineWarnings() { + const deadlineSelected = Array.from(propertySelectionInputs) + .some(cb => cb.value === 'duration_selector' && cb.checked); + document.querySelectorAll('.mumie-no-deadline-warning').forEach(function(elem) { + elem.style.display = deadlineSelected ? '' : 'none'; + }); + } + function setPropertySelectionListeners() { propertySelectionInputs.forEach(function(checkbox) { checkbox.onchange = function() { @@ -478,6 +486,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv selectedTaskProp.push(checkbox.value); } selectedTaskProperties.value = JSON.stringify(selectedTaskProp); + updateNoDeadlineWarnings(); }; }); } diff --git a/mod_form.php b/mod_form.php index 27d28219..2a7947e3 100644 --- a/mod_form.php +++ b/mod_form.php @@ -443,7 +443,7 @@ private function add_task_selection(): void { $label .= html_writer::tag( 'small', ' — ' . get_string('mumie_form_task_no_deadline_warning', 'mod_mumie'), - ['class' => 'text-warning'] + ['class' => 'text-warning mumie-no-deadline-warning', 'style' => 'display:none'] ); } $table->data[] = [$label, $checkboxhtml]; From 21afc2318f0cd5d9c6c96c6e5795902781ce2e98 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 13 May 2026 15:21:27 +0200 Subject: [PATCH 022/101] add error if wrong additional task is selected --- forms/mumie_task_validator.php | 23 +++++++++++++++++++++++ lang/de/mumie.php | 1 + lang/en/mumie.php | 1 + mod_form.php | 1 + 4 files changed, 26 insertions(+) diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index 9addee74..e73942d7 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -50,9 +50,32 @@ public static function get_errors(array $data, \stdClass $current): array { $errors = array_merge($errors, self::check_isgraded($data)); $errors = array_merge($errors, self::check_duration($data)); $errors = array_merge($errors, self::check_worksheet($data)); + $errors = array_merge($errors, self::check_multi_edit_deadline($data)); return $errors; } + /** + * Validates that the Deadline property is only applied to tasks that already have a deadline set. + * + * @param array $data Form data. + * @return array Associative array of validation errors. + */ + private static function check_multi_edit_deadline(array $data): array { + $props = json_decode($data['mumie_selected_task_properties'] ?? '[]', true); + if (!in_array('duration_selector', $props)) { + return []; + } + $taskids = json_decode($data['mumie_selected_tasks'] ?? '[]', true); + foreach ($taskids as $taskid) { + $task = locallib::get_mumie_task((int)$taskid); + if ($task && !($task->duedate > 0)) { + return ['mumie_multi_edit_deadline_error' => + get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie')]; + } + } + return []; + } + /** * Checks whether all required fields are present in the given data array. * diff --git a/lang/de/mumie.php b/lang/de/mumie.php index f24993a3..273a99a7 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -94,6 +94,7 @@ $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_coursefile'] = 'Path to MUMIE course meta file'; +$string['mumie_form_deadline_transfer_invalid'] = 'Deadline kann nur für Tasks übernommen werden, die bereits den Working Period Typ \'Deadline\' haben.'; $string['mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'] = "Das ausgewählte Worksheet darf keinen begrenzten Bearbeitungszeitraum haben.

Wählen Sie ein Worksheet mit entsprechender Konfiguration aus, wenn Sie eine Frist setzen möchten."; $string['mumie_form_deadline_required_for_trigger_after_deadline'] = "Das ausgewählte Worksheet setzt einen festgelegten Bearbeitungszeitraum voraus"; $string['mumie_form_due_date_must_be_future'] = 'Das Datum der Abgabefrist kann nicht in der Vergangenheit liegen!'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 8c5e4547..4e094ebb 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -83,6 +83,7 @@ $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_coursefile'] = 'Path to MUMIE course meta file'; +$string['mumie_form_deadline_transfer_invalid'] = 'Deadline can only be applied to tasks that already have the Working Period type \'Deadline\' set.'; $string['mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'] = "The selected worksheet cannot have a limited working period.

If you want to limit the working period, please select a worksheet with an appropriate configuration."; $string['mumie_form_deadline_required_for_trigger_after_deadline'] = "The selected worksheet requires a limited working period."; $string['mumie_form_due_date_must_be_future'] = 'You must select a date in the future!'; diff --git a/mod_form.php b/mod_form.php index 2a7947e3..075534f2 100644 --- a/mod_form.php +++ b/mod_form.php @@ -338,6 +338,7 @@ private function disable_grade_rules(): void { */ private function add_property_selection(): void { $mform = $this->_form; + $mform->addElement('static', 'mumie_multi_edit_deadline_error', ''); $mform->addElement("hidden", "mumie_selected_task_properties", "[]"); $mform->setType("mumie_selected_task_properties", PARAM_RAW); $taskproperties = [ From c4a83c4cd880b6b8259aee38ddedd19a21db3e59 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 18 May 2026 10:52:28 +0200 Subject: [PATCH 023/101] deactivate Working period selection after task is created --- mod_form.php | 1 + 1 file changed, 1 insertion(+) diff --git a/mod_form.php b/mod_form.php index 075534f2..73192716 100644 --- a/mod_form.php +++ b/mod_form.php @@ -498,6 +498,7 @@ public function set_data($data): void { // This option must not be changed to avoid messing with grades in the database. $mform->updateElementAttr("mumie_complete_course", ["disabled" => "disabled"]); $this->set_grade_data($data, $mform); + $mform->disabledIf('duration_selector', null); parent::set_data($data); } From 6643e6b6f5394502e5d54e5b38c063327d565c9e Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 18 May 2026 11:06:45 +0200 Subject: [PATCH 024/101] correct text postiton --- mod_form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod_form.php b/mod_form.php index 73192716..61fb511a 100644 --- a/mod_form.php +++ b/mod_form.php @@ -346,7 +346,7 @@ private function add_property_selection(): void { [get_string('mumie_form_points', 'mod_mumie'), "points"], [ get_string('mumie_duration_property', 'mod_mumie') - . html_writer::tag('small', get_string('mumie_duration_property_hint', 'mod_mumie'), ['class' => 'form-text text-muted']), + . html_writer::tag('div', get_string('mumie_duration_property_hint', 'mod_mumie'), ['class' => 'form-text text-muted small']), "duration_selector", ], ]; From 894aa56a738825e0fd0477c122e3a510fca29e80 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 18 May 2026 11:19:20 +0200 Subject: [PATCH 025/101] correct error postiton --- mod_form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod_form.php b/mod_form.php index 61fb511a..6d20dc34 100644 --- a/mod_form.php +++ b/mod_form.php @@ -338,7 +338,6 @@ private function disable_grade_rules(): void { */ private function add_property_selection(): void { $mform = $this->_form; - $mform->addElement('static', 'mumie_multi_edit_deadline_error', ''); $mform->addElement("hidden", "mumie_selected_task_properties", "[]"); $mform->setType("mumie_selected_task_properties", PARAM_RAW); $taskproperties = [ @@ -462,6 +461,7 @@ private function add_task_selection(): void { . $htmltables . '' ); + $mform->addElement('static', 'mumie_multi_edit_deadline_error', ''); } /** From ddd1c836ba9fc9dd402ef188699cd7272c01b3c2 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 18 May 2026 11:39:51 +0200 Subject: [PATCH 026/101] correct error postiton --- forms/mumie_task_validator.php | 3 ++- mod_form.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index e73942d7..bade30eb 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -69,8 +69,9 @@ private static function check_multi_edit_deadline(array $data): array { foreach ($taskids as $taskid) { $task = locallib::get_mumie_task((int)$taskid); if ($task && !($task->duedate > 0)) { + $icon = \html_writer::tag('span', '', ['class' => 'icon fa fa-circle-exclamation text-danger fa-fw']); return ['mumie_multi_edit_deadline_error' => - get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie')]; + $icon . get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie')]; } } return []; diff --git a/mod_form.php b/mod_form.php index 6d20dc34..81fc1bf1 100644 --- a/mod_form.php +++ b/mod_form.php @@ -461,7 +461,7 @@ private function add_task_selection(): void { . $htmltables . '' ); - $mform->addElement('static', 'mumie_multi_edit_deadline_error', ''); + $mform->addElement('static', 'mumie_multi_edit_deadline_error', ' '); } /** From c8ffe10fb0b701ba2c17887f320be423f92e71a7 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 18 May 2026 11:54:17 +0200 Subject: [PATCH 027/101] correct error postiton --- mod_form.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mod_form.php b/mod_form.php index 81fc1bf1..864c7d0d 100644 --- a/mod_form.php +++ b/mod_form.php @@ -461,7 +461,13 @@ private function add_task_selection(): void { . $htmltables . '' ); - $mform->addElement('static', 'mumie_multi_edit_deadline_error', ' '); + $mform->addElement('html', ' + + '); + $mform->addElement('static', 'mumie_multi_edit_deadline_error', ''); } /** From 204bd07018a519d59974a3eb314ce9702c07bced Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 18 May 2026 13:25:35 +0200 Subject: [PATCH 028/101] cleanup --- lang/de/mumie.php | 1 - lang/en/mumie.php | 1 - 2 files changed, 2 deletions(-) diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 273a99a7..4568a703 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -118,7 +118,6 @@ $string['mumie_form_server_added'] = 'MUMIE-Server wurde hinzugefügt'; $string['mumie_form_task_properties_selection_info'] = 'Wählen Sie die Eigenschaften dieser MUMIE-Task aus, die in anderen MUMIE-Tasks übernommen werden sollen.'; $string['mumie_form_task_no_deadline_warning'] = 'Bearbeitungszeitraum: keine Deadline'; -$string['mumie_form_tasks_deadline_only'] = 'Es werden nur Tasks mit dem Working Period Typ \'Deadline\' angezeigt.'; $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'; $string['mumie_form_tasks_selection_info'] = 'Bestimmen Sie die MUMIE-Tasks, für die die ausgewählten Eigenschaften ebenfalls übernommen werden sollen.'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 4e094ebb..d8da1e9c 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -112,7 +112,6 @@ $string['mumie_form_server_not_existing'] = 'There is no MUMIE server for this URL'; $string['mumie_form_task_properties_selection_info'] = 'Select the properties of the current MUMIE Task to apply to other MUMIE Tasks.'; $string['mumie_form_task_no_deadline_warning'] = 'Working period: not Deadline'; -$string['mumie_form_tasks_deadline_only'] = 'Only tasks with Working Period type \'Deadline\' are shown.'; $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.'; $string['mumie_form_tasks_selection_info'] = 'Choose the MUMIE Tasks you want to apply the selected changes to.'; From 07a2dc1ab34c2941bd7fc2cd8291781443b1cd20 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 18 May 2026 16:37:14 +0200 Subject: [PATCH 029/101] remove delete_extensions_on_mode_change --- lib.php | 1 - locallib.php | 24 ------------------------ 2 files changed, 25 deletions(-) diff --git a/lib.php b/lib.php index 3901ee29..1d2cf235 100644 --- a/lib.php +++ b/lib.php @@ -78,7 +78,6 @@ function mumie_update_instance($mumie, $mform) { $grades = locallib::has_problem_changed($mumie) ? "reset" : null; mumie_grade_item_update($mumie, $grades); - locallib::delete_extensions_on_mode_change($mumie); $mumie = locallib::clean_up_duration_values($mumie); $calendarservice = new mumie_calendar_service($mumie); $calendarservice->update(); diff --git a/locallib.php b/locallib.php index fbb117f9..c64cbbc4 100644 --- a/locallib.php +++ b/locallib.php @@ -103,30 +103,6 @@ public static function update_pending_gradepool($mumietask) { } } - /** - * Deletes all per-student due date extensions for a MUMIE task if the working period mode has changed. - * Must be called before clean_up_duration_values() so the old mode can still be read from the DB. - * @param stdClass $mumietask the submitted MUMIE task that is supposed to be updated - * @return void - */ - public static function delete_extensions_on_mode_change(stdClass $mumietask): void { - global $DB, $CFG; - if (!property_exists($mumietask, 'duration_selector') || !isset($mumietask->id)) { - return; - } - $oldrecord = $DB->get_record("mumie", ["id" => $mumietask->id]); - if (!$oldrecord) { - return; - } - $oldmode = $oldrecord->duedate > 0 ? 'duedate' - : ($oldrecord->timelimit > 0 ? 'timelimit' - : 'unlimited'); - if ($oldmode !== $mumietask->duration_selector) { - require_once($CFG->dirroot . "/mod/mumie/classes/mumie_duedate_extension.php"); - mumie_duedate_extension::delete_all_for_mumie($mumietask->id); - } - } - /** * The function is called whenever a MUMIE task is created or updated. * Cleans up the submitted duedate and timelimit if not selected in the duration selector. From 2d8cb90fbde9d616ab481b98f088c7a912dd8aac Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 19 May 2026 11:06:18 +0200 Subject: [PATCH 030/101] cleanup --- mod_form.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mod_form.php b/mod_form.php index 864c7d0d..b28e4b35 100644 --- a/mod_form.php +++ b/mod_form.php @@ -345,7 +345,9 @@ private function add_property_selection(): void { [get_string('mumie_form_points', 'mod_mumie'), "points"], [ get_string('mumie_duration_property', 'mod_mumie') - . html_writer::tag('div', get_string('mumie_duration_property_hint', 'mod_mumie'), ['class' => 'form-text text-muted small']), + . html_writer::tag('div', + get_string('mumie_duration_property_hint', 'mod_mumie'), + ['class' => 'form-text text-muted small']), "duration_selector", ], ]; From 3867ff56b1a6b4b3dbd7d6f2a4b8acbf3fe0c392 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 19 May 2026 14:35:23 +0200 Subject: [PATCH 031/101] cleanup --- amd/src/mod_form.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 3298716f..446f54ed 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -466,9 +466,6 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }); } - /** - * Set selection listeners for properties to apply to MUMIE Tasks in the course. - */ function updateNoDeadlineWarnings() { const deadlineSelected = Array.from(propertySelectionInputs) .some(cb => cb.value === 'duration_selector' && cb.checked); @@ -477,6 +474,9 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }); } + /** + * Set selection listeners for properties to apply to MUMIE Tasks in the course. + */ function setPropertySelectionListeners() { propertySelectionInputs.forEach(function(checkbox) { checkbox.onchange = function() { From c986b60045acbba896cd3fdf6842d744d9372e0c Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 19 May 2026 14:53:35 +0200 Subject: [PATCH 032/101] cleanup --- mod_form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod_form.php b/mod_form.php index b28e4b35..528ef984 100644 --- a/mod_form.php +++ b/mod_form.php @@ -506,7 +506,6 @@ public function set_data($data): void { // This option must not be changed to avoid messing with grades in the database. $mform->updateElementAttr("mumie_complete_course", ["disabled" => "disabled"]); $this->set_grade_data($data, $mform); - $mform->disabledIf('duration_selector', null); parent::set_data($data); } @@ -527,6 +526,7 @@ private function set_grade_data($data, $mform): void { } else { $mform->setDefault('duration_selector', 'unlimited'); } + $mform->disabledIf('duration_selector', null); } /** From 7bfb02988cd3ce0570a36e6ae026bb3fc5947f49 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 19 May 2026 16:13:34 +0200 Subject: [PATCH 033/101] moodle style conform --- mod_form.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mod_form.php b/mod_form.php index 528ef984..e731f44a 100644 --- a/mod_form.php +++ b/mod_form.php @@ -345,9 +345,11 @@ private function add_property_selection(): void { [get_string('mumie_form_points', 'mod_mumie'), "points"], [ get_string('mumie_duration_property', 'mod_mumie') - . html_writer::tag('div', + . html_writer::tag( + 'div', get_string('mumie_duration_property_hint', 'mod_mumie'), - ['class' => 'form-text text-muted small']), + ['class' => 'form-text text-muted small'] + ), "duration_selector", ], ]; From febdee4c4b829cfa2a903fa47785ea216768909b Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 19 May 2026 16:21:50 +0200 Subject: [PATCH 034/101] moodle style conform --- amd/src/mod_form.js | 3 +++ classes/privacy/provider.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 446f54ed..436e7912 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -466,6 +466,9 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }); } + /** + * Show or hide per-task "Working period: not Deadline" warnings based on whether the deadline property is selected. + */ function updateNoDeadlineWarnings() { const deadlineSelected = Array.from(propertySelectionInputs) .some(cb => cb.value === 'duration_selector' && cb.checked); diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 48a7db41..5177b942 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -39,7 +39,7 @@ * @author Tobias Goltz (tobias.goltz@integral-learning.de) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\request\core_userlist_provider, \core_privacy\local\metadata\provider, \core_privacy\local\request\plugin\provider { +class provider implements \core_privacy\local\metadata\provider, \core_privacy\local\request\core_userlist_provider, \core_privacy\local\request\plugin\provider { /** * Returns meta data about this system. * From 4c70499c6bb6e6d19ae7ef7e2434e09ae97d6048 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 19 May 2026 17:14:04 +0200 Subject: [PATCH 035/101] moodle style conform --- amd/build/mod_form.min.js | 4 +++- amd/build/mod_form.min.js.map | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 12f64074..1b74c78f 100644 --- a/amd/build/mod_form.min.js +++ b/amd/build/mod_form.min.js @@ -1 +1,3 @@ -define(["jquery","core/templates","core/modal_factory","auth_mumie/mumie_server_config","core/ajax"],function(){let i=document.getElementById("id_add_server_button"),d=document.getElementsByName("mumie_missing_config")[0],m,a,r,l=(()=>{let i=document.getElementById("id_duration_selector"),t=document.getElementById("id_mumie_isgraded");function d(){return"0"===t.value}function e(){d()?(i.setAttribute("disabled","disabled"),i.value="unlimited"):i.removeAttribute("disabled");var e,t="none",n=("unlimited"===i.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t,document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t):"duedate"===i.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display=t,document.getElementById("fitem_id_timelimit").style.display=t,document.getElementById("fitem_id_timelimit_info").style.display=t):"timelimit"===i.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display=t,document.getElementById("fitem_id_duedate_info").style.display=t,document.getElementById("fitem_id_unlimited_info").style.display=t),document.querySelector('[name="mumie_multi_edit_property"][value="duration_selector"]')?.closest("tr"));n&&(e="duedate"===i.value,n.style.display=e?"":t,e||(t=n.querySelector('[name="mumie_multi_edit_property"]'))&&t.checked&&(t.checked=!1,t.dispatchEvent(new Event("change"))))}return{init:function(){i.onchange=function(){e()},window.addEventListener("load",()=>{e()}),e()},setDurationElements:e,isUngraded:d,setGradedElemValue:function(e){t.value=e?"1":"0"},getGradedElemValue:function(){return t.value}}})(),c=(()=>{let n,i=document.getElementById("id_server");return{init:function(e){n=e},getSelectedServer:function(){let t=i.options[i.selectedIndex].text;return n.find(e=>e.name===t)},disable:function(){i.disabled=!0;for(var e=i;e.firstChild;)e.removeChild(e.firstChild)}}})(),o=(()=>{let e=document.getElementById("id_prb_selector_btn"),t=document.getElementById("id_multi_problem_selector_btn"),n,o=document.getElementsByName("mumie_org")[0].value;function i(e){n&&n.postMessage(JSON.stringify(e),m)}function d(e=""){i({success:!0,message:e})}function u(){window.addEventListener("message",t=>{if(t.origin===m){var t=JSON.parse(t.data),e=!1!==t.isGraded,n=t.worksheet??null;try{s.setCourse(t.path_to_coursefile),g.setLanguage(t.language),f.setSelection(t.link,t.language,t.name),f.setIsGraded(e),_.setWorksheet(n),d(),window.focus(),require(["core/str","core/notification"],function(e,t){e.get_strings([{key:"mumie_form_updated_selection",component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0],type:"info"})}).fail(t.exception)})}catch(e){[t=""]=[e.message],i({success:!1,message:t})}}},!1)}function l(){var e,t,n=f.getGradingType(),i=f.getDelocalizedTaskLink(),d=c.getSelectedServer().urlprefix;return e=m,t=d,new URL(e).origin===new URL(t).origin?"/auth/mumie/problem_selector.php?org="+o+"&serverurl="+encodeURIComponent(d)+"&problemlang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+n+"&contextid="+r+(i?"&selection="+i:""):m+"/lms-problem-selector?org="+o+"&serverUrl="+encodeURIComponent(d)+"&problemLang="+g.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+a+"&gradingType="+n+"&multiCourse=true&worksheet=true"+(i?"&selection="+i:"")}return{init:function(){e.onclick=function(){n=window.open(l(),"_blank")},window.onclose=function(){d()},window.addEventListener("beforeunload",function(){d()},!1),u(),t.onclick=function(e){e.preventDefault(),n=window.open(m+"/lms-problem-selector?serverUrl="+encodeURIComponent(c.getSelectedServer().urlprefix)+"&gradingType=all","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){e.disabled=!0}}})(),s=(()=>{let n=document.getElementById("id_mumie_course"),t=document.getElementsByName("mumie_coursefile")[0];function i(){var e=s.getSelectedCourse();let t=g.getSelectedLanguage();e&&t&&(n.value=e.name.find(e=>e.language===t)?.value)}return{init:function(){i()},getSelectedCourse:function(){return c.getSelectedServer().courses.find(e=>e.coursefile===t.value)},setCourse:function(e){e=e,t.value=e,i()}}})(),g=(()=>{let t=document.getElementById("id_language");return{getSelectedLanguage:function(){return t.value},setLanguage:function(e){t.value=e}}})(),f=(()=>{let n=document.getElementsByName("taskurl")[0],i=document.getElementById("id_name"),t=document.getElementById("id_task_display_element"),d="?lang=";function o(e){t.value=e}function u(e,t){t=t;e=e+d+t;o(n.value=e)}return{init:function(){o(n.value)},setSelection:function(e,t,n){u(e,t),e=n,i.value=e},setIsGraded:function(e){l.setGradedElemValue(e),e=l.isUngraded(),document.getElementById("id_points").disabled=e,document.getElementById("id_gradepass").disabled=e,document.getElementById("id_gradecat").disabled=e,l.setDurationElements()},getGradingType:function(){var e=l.getGradedElemValue();return"1"===e?"graded":"0"===e?"ungraded":"all"},getDelocalizedTaskLink:function(){return(e=n.value).includes(d)?e.split(d)[0]:e;var e}}})(),u=(()=>{let e=document.getElementsByName("mumie_multi_edit_property"),n=document.getElementsByName("mumie_selected_task_properties")[0],i=[],t=document.getElementsByName("mumie_multi_edit_task"),d=document.getElementsByName("mumie_selected_tasks")[0],o=[],u=document.getElementsByName("mumie_multi_edit_section");function l(){e.forEach(function(t){t.onchange=function(){t.checked?i.push(t.value):i=i.filter(e=>e!==t.value),n.value=JSON.stringify(i);{let t=Array.from(e).some(e=>"duration_selector"===e.value&&e.checked);document.querySelectorAll(".mumie-no-deadline-warning").forEach(function(e){e.style.display=t?"":"none"})}}})}function m(){u.forEach(function(n){n.onchange=function(){n.checked?t.forEach(function(e){var t;e.getAttribute("section")===n.value&&(e.checked=!0,t=o,e=e.value,t.includes(e)||t.push(e))}):t.forEach(function(t){t.getAttribute("section")===n.value&&(t.checked=!1,o=o.filter(e=>t.value!==e))}),d.value=JSON.stringify(o)}})}return{init:function(){t.forEach(function(t){t.onchange=function(){t.checked?o.push(t.value):o=o.filter(e=>e!==t.value),d.value=JSON.stringify(o)}}),l(),m()}}})(),_=(()=>{let t=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(e){e?t.setAttribute("value",JSON.stringify(e)):t.removeAttribute("value")}}})();function y(n){require(["core/str","core/notification"],function(e,t){e.get_strings([{key:n,component:"mod_mumie"}]).done(function(e){t.addNotification({message:e[0]+""+d.getAttribute("value")+"",type:"problem"})}).fail(t.exception)}),c.disable(),o.disable()}return{init:function(e,t,n){m=t,a=n,r=e;t=document.getElementById("id_name").getAttribute("value"),n=JSON.parse(document.getElementsByName("mumie_server_structure")[0].value);t&&""!==document.getElementsByName("mumie_missing_config")[0].getAttribute("value")?y("mumie_form_missing_server"):n.length?(c.init(n),s.init(),f.init(),u.init(),o.init(),l.init()):y("mumie_form_no_server_conf"),u.init(),i&&require(["auth_mumie/mumie_server_config"],function(e){e.init(i,r)})}}}); \ No newline at end of file +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const durationPropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duration_selector"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(durationPropRow){const show="duedate"===durationSelector.value;if(durationPropRow.style.display=show?"":"none",!show){const cb=durationPropRow.querySelector('[name="mumie_multi_edit_property"]');cb&&cb.checked&&(cb.checked=!1,cb.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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");function setPropertySelectionListeners(){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),function(){const deadlineSelected=Array.from(propertySelectionInputs).some((cb=>"duration_selector"===cb.value&&cb.checked));document.querySelectorAll(".mumie-no-deadline-warning").forEach((function(elem){elem.style.display=deadlineSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 8f31bada..d5063953 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const durationPropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duration_selector\"]')\n ?.closest('tr');\n if (durationPropRow) {\n const show = durationSelector.value === 'duedate';\n durationPropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const cb = durationPropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (cb && cb.checked) {\n cb.checked = false;\n cb.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the deadline property is selected.\n */\n function updateNoDeadlineWarnings() {\n const deadlineSelected = Array.from(propertySelectionInputs)\n .some(cb => cb.value === 'duration_selector' && cb.checked);\n document.querySelectorAll('.mumie-no-deadline-warning').forEach(function(elem) {\n elem.style.display = deadlineSelected ? '' : 'none';\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 updateNoDeadlineWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","durationPropRow","querySelector","_document$querySelect","closest","show","cb","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","forEach","checkbox","push","filter","deadlineSelected","Array","from","some","querySelectorAll","updateNoDeadlineWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","MumieServer"],"mappings":"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"} \ No newline at end of file From d9b03031515c90427d7c1c77f9858a0632ff0122 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 09:44:17 +0200 Subject: [PATCH 036/101] cleanup task_validator --- forms/mumie_task_validator.php | 59 +++++++++++++++++++++------------- version.php | 2 +- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index bade30eb..74ae5909 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -54,29 +54,6 @@ public static function get_errors(array $data, \stdClass $current): array { return $errors; } - /** - * Validates that the Deadline property is only applied to tasks that already have a deadline set. - * - * @param array $data Form data. - * @return array Associative array of validation errors. - */ - private static function check_multi_edit_deadline(array $data): array { - $props = json_decode($data['mumie_selected_task_properties'] ?? '[]', true); - if (!in_array('duration_selector', $props)) { - return []; - } - $taskids = json_decode($data['mumie_selected_tasks'] ?? '[]', true); - foreach ($taskids as $taskid) { - $task = locallib::get_mumie_task((int)$taskid); - if ($task && !($task->duedate > 0)) { - $icon = \html_writer::tag('span', '', ['class' => 'icon fa fa-circle-exclamation text-danger fa-fw']); - return ['mumie_multi_edit_deadline_error' => - $icon . get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie')]; - } - } - return []; - } - /** * Checks whether all required fields are present in the given data array. * @@ -205,6 +182,32 @@ private static function check_worksheet(array $data): array { return $errors; } + /** + * Validates that the Deadline property is only applied to tasks that already have a deadline set. + * + * @param array $data Form data. + * @return array Associative array of validation errors. + */ + private static function check_multi_edit_deadline(array $data): array { + if (!self::is_deadline_property_selected($data)) { + return []; + } + + $errors = []; + $taskids = json_decode($data['mumie_selected_tasks'] ?? '[]', true); + foreach ($taskids as $taskid) { + $task = locallib::get_mumie_task((int)$taskid); + if ($task && !($task->duedate > 0)) { + $icon = \html_writer::tag('span', '', ['class' => 'icon fa fa-circle-exclamation text-danger fa-fw']); + $errors['mumie_selected_tasks'] = get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie'); + break; + #return ['mumie_multi_edit_deadline_error' => + # $icon . get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie')]; + } + } + return $errors; + } + /** * Check whether a duedate was set * @param array $data POST data @@ -242,4 +245,14 @@ private static function is_worksheet(array $data): bool { private static function is_correction_trigger_after_deadline(string $worksheet): bool { return json_decode($worksheet, true)['configuration']['correction']['correctorType'] === "AFTER_DEADLINE"; } + + /** + * Check whether the deadline property is selected for multi-edit transfer. + * @param array $data POST data + * @return bool + */ + private static function is_deadline_property_selected(array $data): bool { + $props = json_decode($data['mumie_selected_task_properties'] ?? '[]', true); + return in_array('duration_selector', $props); + } } diff --git a/version.php b/version.php index 45175157..a120461c 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2026051200; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2026052200; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2022112800; // 4.1 LTS $plugin->release = "v1.9.2"; From 8a4454f486435236ee7492cd8277b8585bfa3124 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 10:10:48 +0200 Subject: [PATCH 037/101] try mumie_multi_edit_deadline_error as errors return element --- forms/mumie_task_validator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index 74ae5909..72cc90be 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -199,7 +199,7 @@ private static function check_multi_edit_deadline(array $data): array { $task = locallib::get_mumie_task((int)$taskid); if ($task && !($task->duedate > 0)) { $icon = \html_writer::tag('span', '', ['class' => 'icon fa fa-circle-exclamation text-danger fa-fw']); - $errors['mumie_selected_tasks'] = get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie'); + $errors['mumie_multi_edit_deadline_error'] = get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie'); break; #return ['mumie_multi_edit_deadline_error' => # $icon . get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie')]; From 3ba3fb317d1827870e28394745292550ca23fae9 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 10:31:52 +0200 Subject: [PATCH 038/101] cleanup mumie_task_validator --- forms/mumie_task_validator.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index 72cc90be..33366d7a 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -163,7 +163,6 @@ private static function check_duration(array $data): array { * @return array Associative array of validation errors. */ private static function check_worksheet(array $data): array { - $isworksheet = self::is_worksheet($data); if (!$isworksheet) { return []; @@ -198,11 +197,9 @@ private static function check_multi_edit_deadline(array $data): array { foreach ($taskids as $taskid) { $task = locallib::get_mumie_task((int)$taskid); if ($task && !($task->duedate > 0)) { - $icon = \html_writer::tag('span', '', ['class' => 'icon fa fa-circle-exclamation text-danger fa-fw']); - $errors['mumie_multi_edit_deadline_error'] = get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie'); + $errors['mumie_multi_edit_deadline_error'] = + get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie'); break; - #return ['mumie_multi_edit_deadline_error' => - # $icon . get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie')]; } } return $errors; From 5d57f1d65b071a544ee55c27441002a278093dfd Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 10:46:14 +0200 Subject: [PATCH 039/101] cleanup double negation --- forms/mumie_task_validator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index 33366d7a..88c3247f 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -196,7 +196,7 @@ private static function check_multi_edit_deadline(array $data): array { $taskids = json_decode($data['mumie_selected_tasks'] ?? '[]', true); foreach ($taskids as $taskid) { $task = locallib::get_mumie_task((int)$taskid); - if ($task && !($task->duedate > 0)) { + if ($task && ($task->duedate <= 0)) { $errors['mumie_multi_edit_deadline_error'] = get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie'); break; From 106121b7439b493d0c48c326b9d13c6004e3b304 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 11:28:20 +0200 Subject: [PATCH 040/101] cahnge text and var naming in lang mumie.php --- forms/mumie_task_validator.php | 2 +- lang/de/mumie.php | 9 ++++----- lang/en/mumie.php | 7 +++---- mod_form.php | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index 88c3247f..1a82d6cf 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -198,7 +198,7 @@ private static function check_multi_edit_deadline(array $data): array { $task = locallib::get_mumie_task((int)$taskid); if ($task && ($task->duedate <= 0)) { $errors['mumie_multi_edit_deadline_error'] = - get_string('mumie_form_deadline_transfer_invalid', 'mod_mumie'); + get_string('mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline', 'mod_mumie'); break; } } diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 4568a703..e1ebf0ef 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -66,14 +66,12 @@ $string['mumie:viewgrades'] = 'Alle Noten einer MUMIE Task in einem Kurs sehen'; $string['mumie_calendar_duedate_desc'] = 'Später Abgaben werden nicht in die Moodle-Bewertungen übernommen'; $string['mumie_calendar_duedate_extension'] = 'Verlängerte Abgabefrist: {$a}'; -$string['mumie_calendar_duedate_name'] = 'Abgabefirst: {$a}'; +$string['mumie_calendar_duedate_name'] = 'Abgabefrist: {$a}'; $string['mumie_due_date'] = 'Abgabefrist'; $string['mumie_due_date_help'] = 'Noten, die nach der ausgewählten Frist erzielt wurden, werden nicht mit Moodle synchronisiert.'; $string['mumie_duedate_extension'] = 'Abfabefristverlängerung'; $string['mumie_duedate_form'] = 'Abgabefrist verlängern'; $string['mumie_duedate_not_set'] = 'Keine allgemeine Abgabefrist für diese MUMIE-Task festgelegt!'; -$string['mumie_duration_property'] = 'Deadline'; -$string['mumie_duration_property_hint'] = 'Deadline kann nur für Tasks übernommen werden, welche vorher bereits mit dem Working Period Typ \'Deadline\' erstellt wurden.'; $string['mumie_duration_selector'] = 'Bearbeitungszeitraum'; $string['mumie_duration_selector_help'] = 'Bei einem begrenzten Bearbeitungszeitraum werden nur die in diesem Zeitraum erzielten Noten mit Moodle synchronisiert.'; $string['mumie_form_activity_container'] = 'Startcontainer'; @@ -94,7 +92,7 @@ $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_coursefile'] = 'Path to MUMIE course meta file'; -$string['mumie_form_deadline_transfer_invalid'] = 'Deadline kann nur für Tasks übernommen werden, die bereits den Working Period Typ \'Deadline\' haben.'; +$string['mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, die bereits den Bearbeitungszeitraum Typ \'Abgabefrist\' haben.'; $string['mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'] = "Das ausgewählte Worksheet darf keinen begrenzten Bearbeitungszeitraum haben.

Wählen Sie ein Worksheet mit entsprechender Konfiguration aus, wenn Sie eine Frist setzen möchten."; $string['mumie_form_deadline_required_for_trigger_after_deadline'] = "Das ausgewählte Worksheet setzt einen festgelegten Bearbeitungszeitraum voraus"; $string['mumie_form_due_date_must_be_future'] = 'Das Datum der Abgabefrist kann nicht in der Vergangenheit liegen!'; @@ -117,10 +115,11 @@ $string['mumie_form_properties'] = 'Eigenschaften'; $string['mumie_form_server_added'] = 'MUMIE-Server wurde hinzugefügt'; $string['mumie_form_task_properties_selection_info'] = 'Wählen Sie die Eigenschaften dieser MUMIE-Task aus, die in anderen MUMIE-Tasks übernommen werden sollen.'; -$string['mumie_form_task_no_deadline_warning'] = 'Bearbeitungszeitraum: keine Deadline'; $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'; $string['mumie_form_tasks_selection_info'] = 'Bestimmen Sie die MUMIE-Tasks, für die die ausgewählten Eigenschaften ebenfalls übernommen werden sollen.'; +$string['mumie_form_due_date_multi_edit_hint'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, welche vorher bereits mit dem Bearbeitungszeitraum Typ \'Abgabefrist\' erstellt wurden.'; +$string['mumie_form_task_no_deadline_warning'] = 'Bearbeitungszeitraum: keine Abgabefrist'; $string['mumie_form_topic'] = 'Thema: {$a}'; $string['mumie_form_updated_selection'] = 'Aufgabe erfolgreich ausgewählt'; $string['mumie_form_wiki_link'] = 'Bitte besuchen Sie unser Wiki für weiterführende Informationen!'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index d8da1e9c..e90c60a9 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -59,8 +59,6 @@ $string['mumie_duedate_extension'] = 'Due date extension'; $string['mumie_duedate_form'] = 'Grant a due date extension'; $string['mumie_duedate_not_set'] = 'No general due date set for this MUMIE Task!'; -$string['mumie_duration_property'] = 'Deadline'; -$string['mumie_duration_property_hint'] = 'Deadline can only be applied to tasks that were previously created with the Working Period type \'Deadline\'.'; $string['mumie_duration_selector'] = 'Working period'; $string['mumie_duration_selector_help'] = 'If the working period is limited, only grades achieved within that period are synchronized with Moodle.'; $string['mumie_form_activity_container'] = 'Launch container'; @@ -83,7 +81,7 @@ $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_coursefile'] = 'Path to MUMIE course meta file'; -$string['mumie_form_deadline_transfer_invalid'] = 'Deadline can only be applied to tasks that already have the Working Period type \'Deadline\' set.'; +$string['mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline'] = 'Deadline can only be applied to tasks that already have the working period type \'Deadline\' set.'; $string['mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'] = "The selected worksheet cannot have a limited working period.

If you want to limit the working period, please select a worksheet with an appropriate configuration."; $string['mumie_form_deadline_required_for_trigger_after_deadline'] = "The selected worksheet requires a limited working period."; $string['mumie_form_due_date_must_be_future'] = 'You must select a date in the future!'; @@ -111,10 +109,11 @@ $string['mumie_form_server_config'] = 'MUMIE server configuration'; $string['mumie_form_server_not_existing'] = 'There is no MUMIE server for this URL'; $string['mumie_form_task_properties_selection_info'] = 'Select the properties of the current MUMIE Task to apply to other MUMIE Tasks.'; -$string['mumie_form_task_no_deadline_warning'] = 'Working period: not Deadline'; $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.'; $string['mumie_form_tasks_selection_info'] = 'Choose the MUMIE Tasks you want to apply the selected changes to.'; +$string['mumie_form_due_date_multi_edit_hint'] = 'Deadline can only be applied to tasks that were previously created with the working period type \'Deadline\'.'; +$string['mumie_form_task_no_deadline_warning'] = 'Working period: not Deadline'; $string['mumie_form_title'] = 'Configure MUMIE Server'; $string['mumie_form_topic'] = 'Topic: {$a}'; $string['mumie_form_updated_selection'] = 'Successfully selected problem'; diff --git a/mod_form.php b/mod_form.php index e731f44a..8052d6b7 100644 --- a/mod_form.php +++ b/mod_form.php @@ -344,10 +344,10 @@ private function add_property_selection(): void { [get_string('mumie_form_activity_container', 'mod_mumie'), "launchcontainer"], [get_string('mumie_form_points', 'mod_mumie'), "points"], [ - get_string('mumie_duration_property', 'mod_mumie') + get_string('mumie_due_date', 'mod_mumie') . html_writer::tag( 'div', - get_string('mumie_duration_property_hint', 'mod_mumie'), + get_string('mumie_form_due_date_multi_edit_hint', 'mod_mumie'), ['class' => 'form-text text-muted small'] ), "duration_selector", From 3d71e236aa2a019e5b7aa7adb0fb2996e225171b Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 11:51:50 +0200 Subject: [PATCH 041/101] remove depricated if in lib.php and use duedate instead --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 4 ++-- forms/mumie_task_validator.php | 14 +++++++------- lib.php | 3 --- mod_form.php | 2 +- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 1b74c78f..c01a2a98 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const durationPropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duration_selector"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(durationPropRow){const show="duedate"===durationSelector.value;if(durationPropRow.style.display=show?"":"none",!show){const cb=durationPropRow.querySelector('[name="mumie_multi_edit_property"]');cb&&cb.checked&&(cb.checked=!1,cb.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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");function setPropertySelectionListeners(){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),function(){const deadlineSelected=Array.from(propertySelectionInputs).some((cb=>"duration_selector"===cb.value&&cb.checked));document.querySelectorAll(".mumie-no-deadline-warning").forEach((function(elem){elem.style.display=deadlineSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const durationPropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(durationPropRow){const show="duedate"===durationSelector.value;if(durationPropRow.style.display=show?"":"none",!show){const cb=durationPropRow.querySelector('[name="mumie_multi_edit_property"]');cb&&cb.checked&&(cb.checked=!1,cb.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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");function setPropertySelectionListeners(){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),function(){const deadlineSelected=Array.from(propertySelectionInputs).some((cb=>"duedate"===cb.value&&cb.checked));document.querySelectorAll(".mumie-no-deadline-warning").forEach((function(elem){elem.style.display=deadlineSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 d5063953..d57a167e 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const durationPropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duration_selector\"]')\n ?.closest('tr');\n if (durationPropRow) {\n const show = durationSelector.value === 'duedate';\n durationPropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const cb = durationPropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (cb && cb.checked) {\n cb.checked = false;\n cb.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the deadline property is selected.\n */\n function updateNoDeadlineWarnings() {\n const deadlineSelected = Array.from(propertySelectionInputs)\n .some(cb => cb.value === 'duration_selector' && cb.checked);\n document.querySelectorAll('.mumie-no-deadline-warning').forEach(function(elem) {\n elem.style.display = deadlineSelected ? '' : 'none';\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 updateNoDeadlineWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","durationPropRow","querySelector","_document$querySelect","closest","show","cb","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","forEach","checkbox","push","filter","deadlineSelected","Array","from","some","querySelectorAll","updateNoDeadlineWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const durationPropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (durationPropRow) {\n const show = durationSelector.value === 'duedate';\n durationPropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const cb = durationPropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (cb && cb.checked) {\n cb.checked = false;\n cb.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the deadline property is selected.\n */\n function updateNoDeadlineWarnings() {\n const deadlineSelected = Array.from(propertySelectionInputs)\n .some(cb => cb.value === 'duedate' && cb.checked);\n document.querySelectorAll('.mumie-no-deadline-warning').forEach(function(elem) {\n elem.style.display = deadlineSelected ? '' : 'none';\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 updateNoDeadlineWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","durationPropRow","querySelector","_document$querySelect","closest","show","cb","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","forEach","checkbox","push","filter","deadlineSelected","Array","from","some","querySelectorAll","updateNoDeadlineWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 436e7912..a65e9cba 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -57,7 +57,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv } const durationPropRow = document - .querySelector('[name="mumie_multi_edit_property"][value="duration_selector"]') + .querySelector('[name="mumie_multi_edit_property"][value="duedate"]') ?.closest('tr'); if (durationPropRow) { const show = durationSelector.value === 'duedate'; @@ -471,7 +471,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv */ function updateNoDeadlineWarnings() { const deadlineSelected = Array.from(propertySelectionInputs) - .some(cb => cb.value === 'duration_selector' && cb.checked); + .some(cb => cb.value === 'duedate' && cb.checked); document.querySelectorAll('.mumie-no-deadline-warning').forEach(function(elem) { elem.style.display = deadlineSelected ? '' : 'none'; }); diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index 1a82d6cf..8444f090 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -50,7 +50,7 @@ public static function get_errors(array $data, \stdClass $current): array { $errors = array_merge($errors, self::check_isgraded($data)); $errors = array_merge($errors, self::check_duration($data)); $errors = array_merge($errors, self::check_worksheet($data)); - $errors = array_merge($errors, self::check_multi_edit_deadline($data)); + $errors = array_merge($errors, self::check_multi_edit_duedate($data)); return $errors; } @@ -182,13 +182,13 @@ private static function check_worksheet(array $data): array { } /** - * Validates that the Deadline property is only applied to tasks that already have a deadline set. + * Validates that the duedate property is only applied to tasks that already have a duedate set. * * @param array $data Form data. * @return array Associative array of validation errors. */ - private static function check_multi_edit_deadline(array $data): array { - if (!self::is_deadline_property_selected($data)) { + private static function check_multi_edit_duedate(array $data): array { + if (!self::is_duedate_property_selected($data)) { return []; } @@ -244,12 +244,12 @@ private static function is_correction_trigger_after_deadline(string $worksheet): } /** - * Check whether the deadline property is selected for multi-edit transfer. + * Check whether the duedate property is selected for multi-edit transfer. * @param array $data POST data * @return bool */ - private static function is_deadline_property_selected(array $data): bool { + private static function is_duedate_property_selected(array $data): bool { $props = json_decode($data['mumie_selected_task_properties'] ?? '[]', true); - return in_array('duration_selector', $props); + return in_array('duedate', $props); } } diff --git a/lib.php b/lib.php index 1d2cf235..911e3037 100644 --- a/lib.php +++ b/lib.php @@ -478,9 +478,6 @@ function mumie_update_multiple_tasks($mumie) { $selectedproperties = json_decode($mumie->mumie_selected_task_properties); $selectedtasks = json_decode($mumie->mumie_selected_tasks); if (!empty($selectedproperties) && !empty($selectedtasks)) { - if (in_array('duration_selector', $selectedproperties)) { - array_push($selectedproperties, 'duedate', 'timelimit'); - } foreach ($selectedtasks as $taskid) { $record = $DB->get_record("mumie", ["id" => $taskid]); foreach ($selectedproperties as $property) { diff --git a/mod_form.php b/mod_form.php index 8052d6b7..c63eda80 100644 --- a/mod_form.php +++ b/mod_form.php @@ -350,7 +350,7 @@ private function add_property_selection(): void { get_string('mumie_form_due_date_multi_edit_hint', 'mod_mumie'), ['class' => 'form-text text-muted small'] ), - "duration_selector", + "duedate", ], ]; $table = new \html_table(); From e741a2e9339bba1a857cd280044f680ce342fe90 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 12:01:05 +0200 Subject: [PATCH 042/101] increase plugin version --- version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.php b/version.php index a120461c..76074474 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2026052200; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2026052201; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2022112800; // 4.1 LTS $plugin->release = "v1.9.2"; From f02416f8e1dfd609f5d1396e747cf31611edbac4 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Fri, 22 May 2026 12:52:52 +0200 Subject: [PATCH 043/101] fix bug cleaning up duration values for multi-edit tasks --- lib.php | 2 -- locallib.php | 19 ------------------- mod_form.php | 29 +++++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/lib.php b/lib.php index 911e3037..aa88e79b 100644 --- a/lib.php +++ b/lib.php @@ -48,7 +48,6 @@ function mumie_add_instance($mumie, $mform) { $mumie->timemodified = $mumie->timecreated; $mumie->use_hashed_id = 1; locallib::update_pending_gradepool($mumie); - $mumie = locallib::clean_up_duration_values($mumie); $mumie->id = $DB->insert_record("mumie", $mumie); mumie_grade_item_update($mumie); $calendarservice = new mumie_calendar_service($mumie); @@ -78,7 +77,6 @@ function mumie_update_instance($mumie, $mform) { $grades = locallib::has_problem_changed($mumie) ? "reset" : null; mumie_grade_item_update($mumie, $grades); - $mumie = locallib::clean_up_duration_values($mumie); $calendarservice = new mumie_calendar_service($mumie); $calendarservice->update(); diff --git a/locallib.php b/locallib.php index c64cbbc4..a7fa5938 100644 --- a/locallib.php +++ b/locallib.php @@ -103,25 +103,6 @@ public static function update_pending_gradepool($mumietask) { } } - /** - * The function is called whenever a MUMIE task is created or updated. - * Cleans up the submitted duedate and timelimit if not selected in the duration selector. - * @param stdClass $mumietask the submitted MUMIE task that is supposed to be created or updated - * @return stdClass the MUMIE task with cleaned duration values - */ - public static function clean_up_duration_values(stdClass $mumietask): stdClass { - $workingperiod = $mumietask->duration_selector; - if (isset($workingperiod)) { - if ($workingperiod != 'duedate') { - $mumietask->duedate = 0; - } - if ($workingperiod != 'timelimit') { - $mumietask->timelimit = 0; - } - } - return $mumietask; - } - /** * Get a default name for the uploaded MumieTask, if available. * diff --git a/mod_form.php b/mod_form.php index c63eda80..f5f898d3 100644 --- a/mod_form.php +++ b/mod_form.php @@ -260,6 +260,35 @@ public function validation($data, $files): array { return \mod_mumie\mumie_task_validator::get_errors($data, $this->current); } + /** + * Post-process submitted form data before it is handed to mumie_(add|update)_instance. + * + * @param stdClass $data Submitted form data (mutated in place). + */ + public function data_postprocessing($data): void + { + parent::data_postprocessing($data); + self::clean_up_duration_values($data); + } + + /** + * Zero the duration column that does not match duration_selector. + * + * The form exposes duedate and timelimit side by side with duration_selector choosing + * which one is active. This enforces the invariant "only the active column is non-zero" + * before the data is handed to the persistence layer. + * + * @param stdClass $data Submitted form data (mutated in place). + */ + private static function clean_up_duration_values(stdClass $data): void { + if ($data->duration_selector !== 'duedate') { + $data->duedate = 0; + } + if ($data->duration_selector !== 'timelimit') { + $data->timelimit = 0; + } + } + /** * Get all options for server drop-down menu * From 62675f0ec214349193df5e1a88065089db3f2034 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 16:17:30 +0200 Subject: [PATCH 044/101] refactor naming, mostly deadline to duedate --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 28 ++++++++++++++-------------- lang/de/mumie.php | 2 +- lang/en/mumie.php | 2 +- mod_form.php | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index c01a2a98..87bdacf1 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const durationPropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(durationPropRow){const show="duedate"===durationSelector.value;if(durationPropRow.style.display=show?"":"none",!show){const cb=durationPropRow.querySelector('[name="mumie_multi_edit_property"]');cb&&cb.checked&&(cb.checked=!1,cb.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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");function setPropertySelectionListeners(){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),function(){const deadlineSelected=Array.from(propertySelectionInputs).some((cb=>"duedate"===cb.value&&cb.checked));document.querySelectorAll(".mumie-no-deadline-warning").forEach((function(elem){elem.style.display=deadlineSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 d57a167e..fdb21230 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const durationPropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (durationPropRow) {\n const show = durationSelector.value === 'duedate';\n durationPropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const cb = durationPropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (cb && cb.checked) {\n cb.checked = false;\n cb.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the deadline property is selected.\n */\n function updateNoDeadlineWarnings() {\n const deadlineSelected = Array.from(propertySelectionInputs)\n .some(cb => cb.value === 'duedate' && cb.checked);\n document.querySelectorAll('.mumie-no-deadline-warning').forEach(function(elem) {\n elem.style.display = deadlineSelected ? '' : 'none';\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 updateNoDeadlineWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","durationPropRow","querySelector","_document$querySelect","closest","show","cb","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","forEach","checkbox","push","filter","deadlineSelected","Array","from","some","querySelectorAll","updateNoDeadlineWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","MumieServer"],"mappings":"AAAAA,4BAAO,CAAC,SAAU,iBAAkB,qBAAsB,iCAAkC,cACxF,iBACUC,gBAAkBC,SAASC,eAAe,wBAC1CC,cAAgBF,SAASG,kBAAkB,wBAAwB,OACrEC,eACAC,eACAC,gBAGEC,mBAAsB,iBAElBC,iBAAmBR,SAASC,eAAe,wBAC3CQ,WAAaT,SAASC,eAAe,8BAKlCS,mBACuB,MAArBD,WAAWE,eAMbC,mDACYF,cAEbF,iBAAiBK,aAAa,WAAY,YAC1CL,iBAAiBG,MAAQ,aAEzBH,iBAAiBM,gBAAgB,YAKN,cAA3BN,iBAAiBG,OACjBX,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,sBAAsBc,MAAMC,QALpC,OAMhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QANzC,OAOhBhB,SAASC,eAAe,oBAAoBc,MAAMC,QAPlC,OAQhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QARvC,QASkB,YAA3BR,iBAAiBG,OACxBX,SAASC,eAAe,oBAAoBc,MAAMC,QAAU,GAC5DhB,SAASC,eAAe,yBAAyBc,MAAMC,QAAU,GAEjEhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAbzC,OAchBhB,SAASC,eAAe,sBAAsBc,MAAMC,QAdpC,OAehBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAfzC,QAgBkB,cAA3BR,iBAAiBG,QACxBX,SAASC,eAAe,sBAAsBc,MAAMC,QAAU,GAC9DhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,oBAAoBc,MAAMC,QApBlC,OAqBhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QArBvC,OAsBhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAtBzC,cAyBdC,8CAAkBjB,SACnBkB,cAAc,+FADKC,sBAElBC,QAAQ,SACVH,gBAAiB,OACXI,KAAkC,YAA3Bb,iBAAiBG,SAC9BM,gBAAgBF,MAAMC,QAAUK,KAAO,GA9BvB,QA+BXA,KAAM,OACDC,GAAKL,gBAAgBC,cAAc,sCACrCI,IAAMA,GAAGC,UACTD,GAAGC,SAAU,EACbD,GAAGE,cAAc,IAAIC,MAAM,oBAMpC,CACHC,KAAM,WACFlB,iBAAiBmB,SAAW,WACxBf,0BAEJgB,OAAOC,iBAAiB,QAAQ,KAC5BjB,4BAEJA,0BAEJkB,oBAAqBlB,uBACrBF,WAAYA,WACZqB,mBAAoB,SAASC,UACzBvB,WAAWE,MAAQqB,SAAW,IAAM,KAExCC,mBAAoB,kBACTxB,WAAWE,QAjFF,GAsFtBuB,iBAAoB,eAClBC,sBACEC,eAAiBpC,SAASC,eAAe,mBAExC,CACHyB,KAAM,SAASW,WACXF,gBAAkBE,WAEtBC,kBAAmB,iBACTC,mBAAqBH,eAAeI,QAAQJ,eAAeK,eAAeC,YACzEP,gBAAgBQ,MAAKC,QAAUA,OAAOC,OAASN,sBAE1DO,QAAS,WACLV,eAAeW,UAAW,WAweZC,WACfA,KAAKC,YACRD,KAAKE,YAAYF,KAAKC,YAzelBE,CAAiBf,kBAdH,GAmBpBgB,0BAA6B,iBACzBC,sBAAwBrD,SAASC,eAAe,uBAChDqD,2BAA6BtD,SAASC,eAAe,qCACvDsD,4BACEC,SAAWxD,SAASG,kBAAkB,aAAa,GAAGQ,eAQnD8C,aAAaC,UACbH,uBAGLA,sBAAsBI,YAAYC,KAAKC,UAAUH,UAAWtD,yBAOvD0D,kBAAYC,+DAAU,GAC3BN,aAAa,CACTO,SAAS,EACTD,QAASA,mBAkBRE,qBACLrC,OAAOC,iBAAiB,WAAYqC,oCAC5BA,MAAMC,SAAW/D,4BAGfgE,UAAYR,KAAKS,MAAMH,MAAMI,MAC7BtC,UAAkC,IAAvBoC,UAAUpC,SACrBuC,uCAAYH,UAAUG,+DAAa,SAErCC,iBAAiBC,UAAUL,UAAUM,oBACrCC,eAAeC,YAAYR,UAAUS,UACrCC,eAAeC,aAAaX,UAAUY,KAAMZ,UAAUS,SAAUT,UAAUvB,MAC1EiC,eAAeG,YAAYjD,UAC3BkD,oBAAoBC,aAAaZ,WACjCT,cACAlC,OAAOwD,QAYfC,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN,+BACPC,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzB7B,QAAS4B,EAAE,GACXE,KAAM,YAEXC,KAAKP,aAAaQ,cAnBnB,MAAOC,mBA1BbvC,aAAa,CACTO,SAAS,EACTD,+DAHuB,KA4BnBkC,CAAYD,MAAMjC,aAEvB,YAwBEmC,iBACCC,YAAcrB,eAAesB,iBAC7BC,UAAYvB,eAAewB,yBAC3BC,eAAiBrE,iBAAiBI,oBAAoBkE,cAwCtBC,yBAAAA,kBAvCMF,eAwCrC,IAAIG,IAxCiBtG,gBAwCO+D,SAAW,IAAIuC,IAAID,mBAAmBtC,QAtC9D,wCAEHX,SACA,cACAmD,mBAAmBJ,gBACnB,gBACA5B,eAAeiC,sBACf,WAAaD,mBAAmB/E,OAAOiF,SAAS1C,QAChD,gBAAkBgC,YAClB,cAAgB7F,WACf+F,UAAY,cAAgBA,UAAY,IAE1CjG,eAAAA,6BAGHoD,SACA,cACAmD,mBAAmBJ,gBACnB,gBACA5B,eAAeiC,sBACf,WAAaD,mBAAmB/E,OAAOiF,SAAS1C,QAChD,WAAa9D,eACb,gBAAkB8F,YAVf/F,oCAaFiG,UAAY,cAAgBA,UAAY,UAgB1C,CACH3E,KAAM,WACF2B,sBAAsByD,QAAU,WAC5BvD,sBAAwB3B,OAAOmF,KAAKb,WAAY,WAGpDtE,OAAOoF,QAAU,WACblD,eAGJlC,OAAOC,iBAAiB,gBAAgB,WACpCiC,iBACD,GAEHG,qBAEAX,2BAA2BwD,QAAU,SAASG,GAC1CA,EAAEC,iBACF3D,sBAAwB3B,OAAOmF,KAC3B3G,eAAAA,mCAGAuG,mBAAmBzE,iBAAiBI,oBAAoBkE,WACxD,mBACA,SACA,oCAIZ1D,QAAS,WACLO,sBAAsBN,UAAW,IArKV,GA0K7ByB,iBAAoB,iBAChB2C,eAAiBnH,SAASC,eAAe,mBACzCmH,eAAiBpH,SAASG,kBAAkB,oBAAoB,YAgB7DkH,mDACCC,eAAiB9C,iBAAiB+C,oBAClCC,iBAAmB7C,eAAeiC,sBACnCU,gBAAmBE,mBAGxBL,eAAexG,oCAAQ2G,eAAezE,KACjCF,MAAK8E,aAAeA,YAAY5C,WAAa2C,2DAD3BE,sBAC8C/G,aAGlE,CACHe,KAAM,WACF2F,oBAEJE,kBAAmB,kBACCrF,iBAAiBI,oBAAoBqF,QACtChF,MAAKiF,QAAUA,OAAOC,aAAeT,eAAezG,SAEvE8D,UAAW,SAASqD,gBA1BMD,WAAAA,WA2BDC,WA1BzBV,eAAezG,MAAQkH,WACvBR,qBAZkB,GA0CpB1C,eAAkB,iBACdoD,aAAe/H,SAASC,eAAe,qBACtC,CACH2G,oBAAqB,kBACVmB,aAAapH,OAExBiE,YAAa,SAASoD,MAClBD,aAAapH,MAAQqH,OAPT,GAYlBlD,eAAkB,iBACdmD,mBAAqBjI,SAASG,kBAAkB,WAAW,GAC3D+H,SAAWlI,SAASC,eAAe,WACnCkI,mBAAqBnI,SAASC,eAAe,oCAc1CmI,yBAAyBC,eAC9BF,mBAAmBxH,MAAQ0H,uBAQtBC,cAActD,KAAMH,gBACnBwD,uBAWYrD,KAAMH,iBACjBG,KAnCuB,SAmCYH,SAZpB0D,CAAavD,KAAMH,UACzCoD,mBAAmBtH,MAAQ0H,cAC3BD,yBAAyBC,qBAoCtB,CACH3G,KAAM,WACF0G,yBAAyBH,mBAAmBtH,QAEhDoE,aAAc,SAASC,KAAMH,SAAUhC,MACnCyF,cAActD,KAAMH,mBA5DRhC,MAChBqF,SAASvH,MAAQkC,KA4Db2F,CAAW3F,OAEfoC,YAAa,SAASjD,UAClBzB,mBAAmBwB,mBAAmBC,2BAhBpCe,SAAWxC,mBAAmBG,aACpCV,SAASC,eAAe,aAAa8C,SAAWA,SAChD/C,SAASC,eAAe,gBAAgB8C,SAAWA,SACnD/C,SAASC,eAAe,eAAe8C,SAAWA,SAClDxC,mBAAmBuB,sBAaf2G,IAEJrC,eAAgB,iBACNpE,SAAWzB,mBAAmB0B,2BACnB,MAAbD,SACO,SACa,MAAbA,SACA,WAEJ,OAEXsE,uBAAwB,kBAvCJtB,KAwCMiD,mBAAmBtH,OAvCpC+H,SA5CqB,UA6CnB1D,KAAK2D,MA7Cc,UA6CmB,GAE1C3D,SAJaA,OA/CJ,GA6FlB4D,wBAA2B,iBACvBC,wBAA0B7I,SAASG,kBAAkB,6BACrD2I,uBAAyB9I,SAASG,kBAAkB,kCAAkC,OACxF4I,iBAAmB,SACjBC,oBAAsBhJ,SAASG,kBAAkB,yBACjD8I,cAAgBjJ,SAASG,kBAAkB,wBAAwB,OACrE+I,gBAAkB,SAChBC,cAAgBnJ,SAASG,kBAAkB,qCA4CxCiJ,gCACLP,wBAAwBQ,SAAQ,SAASC,UACrCA,SAAS3H,SAAW,WACX2H,SAAS/H,QAGVwH,iBAAiBQ,KAAKD,SAAS3I,OAF/BoI,iBAAmBA,iBAAiBS,QAAOxG,MAAQA,OAASsG,SAAS3I,QAIzEmI,uBAAuBnI,MAAQiD,KAAKC,UAAUkF,mCAlBhDU,iBAAmBC,MAAMC,KAAKd,yBAC/Be,MAAKtI,IAAmB,YAAbA,GAAGX,OAAuBW,GAAGC,UAC7CvB,SAAS6J,iBAAiB,8BAA8BR,SAAQ,SAASrG,MACrEA,KAAKjC,MAAMC,QAAUyI,iBAAmB,GAAK,UAgBzCK,aA+BL,CACHpI,KAAM,WAnENsH,oBAAoBK,SAAQ,SAASC,UACjCA,SAAS3H,SAAW,WACX2H,SAAS/H,QAGV2H,gBAAgBK,KAAKD,SAAS3I,OAF9BuI,gBAAkBA,gBAAgBM,QAAOxG,MAAQA,OAASsG,SAAS3I,QAIvEsI,cAActI,MAAQiD,KAAKC,UAAUqF,qBA8DzCE,gCAzBJD,cAAcE,SAAQ,SAASU,iBAC3BA,gBAAgBpI,SAAW,WAClBoI,gBAAgBxI,QAQjByH,oBAAoBK,SAAQ,SAASW,kBAhE5BC,MAAOC,QAiERF,aAAaG,aAAa,aAAeJ,gBAAgBpJ,QACzDqJ,aAAazI,SAAU,EAlEtB0I,MAmEef,gBAnERgB,QAmEyBF,aAAarJ,MAlE7DsJ,MAAMvB,SAASwB,UAChBD,MAAMV,KAAKW,aAuDHlB,oBAAoBK,SAAQ,SAASW,cAC7BA,aAAaG,aAAa,aAAeJ,gBAAgBpJ,QACzDqJ,aAAazI,SAAU,EACvB2H,gBAAkBA,gBAAgBM,QAAOxG,MAAQgH,aAAarJ,QAAUqC,WAWpFiG,cAActI,MAAQiD,KAAKC,UAAUqF,uBAtFpB,GAoG3BhE,oBAAuB,iBACnBkF,iBAAmBpK,SAASC,eAAe,4BAC1C,CACHkF,aAAc,SAASZ,WACfA,UACA6F,iBAAiBvJ,aAAa,QAAS+C,KAAKC,UAAUU,YAEtD6F,iBAAiBtJ,gBAAgB,WAPpB,YAiBpBuJ,qBAAqBC,UAC1BjF,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN8E,SACP7E,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzB7B,QAAS4B,EAAE,GAAK,MAAQzF,cAAciK,aAAa,SAAW,OAC9DtE,KAAM,eAEXC,KAAKP,aAAaQ,cAEzB7D,iBAAiBY,UACjBM,0BAA0BN,gBAGvB,CACHpB,KAAM,SAAS6I,eAAgBC,eAAgBxC,MAC3C5H,eAAiBoK,eACjBnK,eAAiB2H,KACjB1H,UAAYiK,qBACNE,OAASzK,SAASC,eAAe,WAAWkK,aAAa,SACzDhI,gBAAkByB,KAAKS,MAAMrE,SAASG,kBAAkB,0BAA0B,GAAGQ,OACvF8J,QAoC+E,KAAhFzK,SAASG,kBAAkB,wBAAwB,GAAGgK,aAAa,SAnClEE,qBAAqB,6BACblI,gBAAgBuI,QAGxBxI,iBAAiBR,KAAKS,iBACtBqC,iBAAiB9C,OACjBoD,eAAepD,OACfkH,wBAAwBlH,OACxB0B,0BAA0B1B,OAC1BnB,mBAAmBmB,QAPnB2I,qBAAqB,6BASzBzB,wBAAwBlH,OACpB3B,iBACAsF,QAAQ,CAAC,mCAAmC,SAASsF,aACjDA,YAAYjJ,KAAK3B,gBAAiBO"} \ 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","forEach","checkbox","push","filter","duedateSelected","Array","from","some","querySelectorAll","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 a65e9cba..1e43c90b 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -56,17 +56,17 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv document.getElementById('fitem_id_unlimited_info').style.display = displayNone; } - const durationPropRow = document + const duedatePropRow = document .querySelector('[name="mumie_multi_edit_property"][value="duedate"]') ?.closest('tr'); - if (durationPropRow) { + if (duedatePropRow) { const show = durationSelector.value === 'duedate'; - durationPropRow.style.display = show ? '' : displayNone; + duedatePropRow.style.display = show ? '' : displayNone; if (!show) { - const cb = durationPropRow.querySelector('[name="mumie_multi_edit_property"]'); - if (cb && cb.checked) { - cb.checked = false; - cb.dispatchEvent(new Event('change')); + const duedatePropertyCheckbox = duedatePropRow.querySelector('[name="mumie_multi_edit_property"]'); + if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) { + duedatePropertyCheckbox.checked = false; + duedatePropertyCheckbox.dispatchEvent(new Event('change')); } } } @@ -467,13 +467,13 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv } /** - * Show or hide per-task "Working period: not Deadline" warnings based on whether the deadline property is selected. + * Show or hide per-task "Working period: not Deadline" warnings based on whether the duedate property is selected. */ - function updateNoDeadlineWarnings() { - const deadlineSelected = Array.from(propertySelectionInputs) - .some(cb => cb.value === 'duedate' && cb.checked); - document.querySelectorAll('.mumie-no-deadline-warning').forEach(function(elem) { - elem.style.display = deadlineSelected ? '' : 'none'; + function updateNoDuedateWarnings() { + const duedateSelected = Array.from(propertySelectionInputs) + .some(checkbox => checkbox.value === 'duedate' && checkbox.checked); + document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) { + elem.style.display = duedateSelected ? '' : 'none'; }); } @@ -489,7 +489,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv selectedTaskProp.push(checkbox.value); } selectedTaskProperties.value = JSON.stringify(selectedTaskProp); - updateNoDeadlineWarnings(); + updateNoDuedateWarnings(); }; }); } diff --git a/lang/de/mumie.php b/lang/de/mumie.php index e1ebf0ef..b9563ac7 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -119,7 +119,7 @@ $string['mumie_form_tasks_edit_info'] = 'Sie können einige der oben gewählten Einstellungen auch automatisch in anderen MUMIE-Tasks dieses Kurses übernehmen'; $string['mumie_form_tasks_selection_info'] = 'Bestimmen Sie die MUMIE-Tasks, für die die ausgewählten Eigenschaften ebenfalls übernommen werden sollen.'; $string['mumie_form_due_date_multi_edit_hint'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, welche vorher bereits mit dem Bearbeitungszeitraum Typ \'Abgabefrist\' erstellt wurden.'; -$string['mumie_form_task_no_deadline_warning'] = 'Bearbeitungszeitraum: keine Abgabefrist'; +$string['mumie_form_working_period_not_duedate_warning'] = 'Bearbeitungszeitraum: keine Abgabefrist'; $string['mumie_form_topic'] = 'Thema: {$a}'; $string['mumie_form_updated_selection'] = 'Aufgabe erfolgreich ausgewählt'; $string['mumie_form_wiki_link'] = 'Bitte besuchen Sie unser Wiki für weiterführende Informationen!'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index e90c60a9..0e8635cd 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -113,7 +113,7 @@ $string['mumie_form_tasks_edit_info'] = 'You can apply some of the settings selected above also automatically to other MUMIE Tasks of this course.'; $string['mumie_form_tasks_selection_info'] = 'Choose the MUMIE Tasks you want to apply the selected changes to.'; $string['mumie_form_due_date_multi_edit_hint'] = 'Deadline can only be applied to tasks that were previously created with the working period type \'Deadline\'.'; -$string['mumie_form_task_no_deadline_warning'] = 'Working period: not Deadline'; +$string['mumie_form_working_period_not_duedate_warning'] = 'Working period: not Deadline'; $string['mumie_form_title'] = 'Configure MUMIE Server'; $string['mumie_form_topic'] = 'Topic: {$a}'; $string['mumie_form_updated_selection'] = 'Successfully selected problem'; diff --git a/mod_form.php b/mod_form.php index f5f898d3..a8d28e4a 100644 --- a/mod_form.php +++ b/mod_form.php @@ -475,8 +475,8 @@ private function add_task_selection(): void { if (!($module->duedate > 0)) { $label .= html_writer::tag( 'small', - ' — ' . get_string('mumie_form_task_no_deadline_warning', 'mod_mumie'), - ['class' => 'text-warning mumie-no-deadline-warning', 'style' => 'display:none'] + ' — ' . get_string('mumie_form_working_period_not_duedate_warning', 'mod_mumie'), + ['class' => 'text-warning mumie-form-working-period-not-duedate-warning', 'style' => 'display:none'] ); } $table->data[] = [$label, $checkboxhtml]; From 574a80a03dbbaf83d8d0230098972bba373e26c9 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 22 May 2026 16:29:12 +0200 Subject: [PATCH 045/101] correct formatting --- classes/privacy/provider.php | 5 ++++- forms/mumie_task_validator.php | 2 +- mod_form.php | 3 +-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 5177b942..1c0bda61 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -39,7 +39,10 @@ * @author Tobias Goltz (tobias.goltz@integral-learning.de) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\provider, \core_privacy\local\request\core_userlist_provider, \core_privacy\local\request\plugin\provider { +class provider implements + \core_privacy\local\metadata\provider, + \core_privacy\local\request\core_userlist_provider, + \core_privacy\local\request\plugin\provider { /** * Returns meta data about this system. * diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index 8444f090..25795a11 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -187,7 +187,7 @@ private static function check_worksheet(array $data): array { * @param array $data Form data. * @return array Associative array of validation errors. */ - private static function check_multi_edit_duedate(array $data): array { + private static function check_multi_edit_duedate(array $data): array { if (!self::is_duedate_property_selected($data)) { return []; } diff --git a/mod_form.php b/mod_form.php index a8d28e4a..151334f7 100644 --- a/mod_form.php +++ b/mod_form.php @@ -265,8 +265,7 @@ public function validation($data, $files): array { * * @param stdClass $data Submitted form data (mutated in place). */ - public function data_postprocessing($data): void - { + public function data_postprocessing($data): void { parent::data_postprocessing($data); self::clean_up_duration_values($data); } From 18060108e871ac7a7518428aa4e99fcaf00d1270 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 26 May 2026 09:43:11 +0200 Subject: [PATCH 046/101] reset version.php until decision --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 76074474..7fb99e9b 100644 --- a/version.php +++ b/version.php @@ -25,10 +25,10 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2026052201; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2026052200; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2022112800; // 4.1 LTS -$plugin->release = "v1.9.2"; +$plugin->release = "v1.9.1"; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = [ 'auth_mumie' => 2025051500, From 883cf9d1f2e0bd92fb281c86457ca16cd49a0a52 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 26 May 2026 09:45:09 +0200 Subject: [PATCH 047/101] reset version.php until decision --- version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.php b/version.php index 7fb99e9b..d7e9063f 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2026052200; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2025070300; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2022112800; // 4.1 LTS $plugin->release = "v1.9.1"; From 3c4dc4b339e6c7121232042142fd735fc6d9a30b Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 26 May 2026 09:46:34 +0200 Subject: [PATCH 048/101] update changelog --- changelog.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/changelog.md b/changelog.md index d1457474..1a0be6f4 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,16 @@ All important changes to this plugin will be documented in this file. +## TODO +### Added +- Teachers can now apply the deadline setting to multiple MUMIE Tasks at once using the multi-edit feature +- Tasks without a 'Deadline' working period show a warning when deadline transfer is selected +- Validation prevents transferring a deadline to tasks that were not created with working period type 'Deadline' + +### Fixed +- MUMIE Task no longer shows working period descriptions for all options simultaneously +- Inconsistent working period description texts corrected + ## [v1.9.1] - 2025-07-03 ### Changed - Refactored code to comply with PHP 8.4 From abaed88b03865093dac8372a411e882dd7a229f8 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 1 Jun 2026 16:01:15 +0200 Subject: [PATCH 049/101] implement multi slect without drag and drop --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 87 ++++++++++++++++++++- db/services.php | 8 ++ externallib.php | 137 ++++++++++++++++++++++++++++++++++ mod_form.php | 3 + 6 files changed, 235 insertions(+), 4 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 90c6e116..2163d3bc 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return void function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const names=tasks.map((t=>t.name)).join(", ");summary.textContent=tasks.length+" tasks selected: "+names,summary.style.display="block"}document.getElementById("id_name").disabled=!0,sendSuccess(),window.focus()}(importObj);const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0,problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&gradingType=all&origin="+encodeURIComponent(window.location.origin)+"&multiSelect=true","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formdata=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[k,v]=_ref2;return encodeURIComponent(k)+"="+encodeURIComponent(v)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formdata}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");form&&form.addEventListener("submit",(function(e){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&tasksField.value&&(e.preventDefault(),problemSelectorController.submitMultiTasks())}))}}})); //# 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 8f31bada..4d098c15 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","filter","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formdata = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formdata,\n };\n }\n\n /**\n * Handle multi-select postMessage: store tasks and show summary so teacher can adjust settings.\n * @param {Array} tasks array of task objects from the selector\n */\n function handleMultiSelect(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const names = tasks.map(t => t.name).join(', ');\n summary.textContent = tasks.length + ' tasks selected: ' + names;\n summary.style.display = 'block';\n }\n document.getElementById('id_name').disabled = true;\n sendSuccess();\n window.focus();\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\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\n if (Array.isArray(importObj)) {\n handleMultiSelect(importObj);\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n problemSelectorWindow = window.open(\n lmsSelectorUrl +\n '/lms-problem-selector?' +\n \"serverUrl=\" +\n encodeURIComponent(serverController.getSelectedServer().urlprefix) +\n '&gradingType=all' +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&multiSelect=true',\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n submitMultiTasks: submitMultiTasks,\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n form.addEventListener('submit', function(e) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField && tasksField.value) {\n e.preventDefault();\n problemSelectorController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","tasks","tasksField","summary","names","map","t","join","textContent","length","focus","handleMultiSelect","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","submitMultiTasks","courseId","_document$getElements","settings","section","parseInt","URLSearchParams","search","get","submitBtn","form","closest","sensitiveFields","formdata","from","FormData","filter","_ref","key","includes","_ref2","k","v","contextid","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","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 c7ba5436..4c5832de 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -138,6 +138,67 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }); } + /** + * Collect current form settings for multi-task creation. + * @returns {Object} form settings + */ + function collectFormSettings() { + const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0); + const submitBtn = document.getElementById('id_submitbutton'); + const form = submitBtn && submitBtn.closest('form'); + const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form']; + const formdata = form + ? Array.from(new FormData(form)) + .filter(([key]) => !sensitiveFields.includes(key)) + .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v)) + .join('&') + : ''; + return { + contextid: parseInt(contextId), + section: section, + formdata: formdata, + }; + } + + /** + * Handle multi-select postMessage: store tasks and show summary so teacher can adjust settings. + * @param {Array} tasks array of task objects from the selector + */ + function handleMultiSelect(tasks) { + const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; + const summary = document.getElementById('mumie_multi_tasks_summary'); + if (tasksField) { + tasksField.value = JSON.stringify(tasks); + } + if (summary) { + const names = tasks.map(t => t.name).join(', '); + summary.textContent = tasks.length + ' tasks selected: ' + names; + summary.style.display = 'block'; + } + document.getElementById('id_name').disabled = true; + sendSuccess(); + window.focus(); + } + + /** + * Submit multi-tasks via AJAX using current form settings, then redirect to course. + */ + function submitMultiTasks() { + const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; + const courseId = document.getElementsByName('course')[0]?.value; + const settings = collectFormSettings(); + settings.tasks = tasksField.value; + + require(['core/ajax', 'core/notification'], function(Ajax, Notification) { + Ajax.call([{ + methodname: 'mod_mumie_create_multiple_tasks', + args: settings, + }])[0].done(function() { + window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; + }).fail(Notification.exception); + }); + } + /** * Add an event listener that accepts messages from LMS-Browser and updates the selected problem. */ @@ -147,6 +208,12 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv return; } const importObj = JSON.parse(event.data); + + if (Array.isArray(importObj)) { + handleMultiSelect(importObj); + return; + } + const isGraded = importObj.isGraded !== false; const worksheet = importObj.worksheet ?? null; try { @@ -250,12 +317,15 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv multiProblemSelectorButton.onclick = function(e) { e.preventDefault(); + document.getElementById('id_name').disabled = true; problemSelectorWindow = window.open( lmsSelectorUrl + '/lms-problem-selector?' + "serverUrl=" + encodeURIComponent(serverController.getSelectedServer().urlprefix) + - '&gradingType=all', + '&gradingType=all' + + '&origin=' + encodeURIComponent(window.location.origin) + + '&multiSelect=true', "_blank", 'toolbar=0,location=0,menubar=0' ); @@ -263,7 +333,8 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }, disable: function() { problemSelectorButton.disabled = true; - } + }, + submitMultiTasks: submitMultiTasks, }; })(); @@ -560,6 +631,18 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv MumieServer.init(addServerButton, contextId); }); } + + const submitBtn = document.getElementById('id_submitbutton'); + const form = submitBtn && submitBtn.closest('form'); + if (form) { + form.addEventListener('submit', function(e) { + const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; + if (tasksField && tasksField.value) { + e.preventDefault(); + problemSelectorController.submitMultiTasks(); + } + }); + } } }; diff --git a/db/services.php b/db/services.php index 03c4f555..661cd768 100644 --- a/db/services.php +++ b/db/services.php @@ -34,4 +34,12 @@ 'ajax' => true, 'type' => 'write', ], + 'mod_mumie_create_multiple_tasks' => [ + 'classname' => 'mod_mumie_external', + 'methodname' => 'create_multiple_tasks', + 'classpath' => 'mod/mumie/externallib.php', + 'description' => 'Creates multiple MUMIE Tasks at once with shared settings', + 'ajax' => true, + 'type' => 'write', + ], ]; diff --git a/externallib.php b/externallib.php index 3c0ea6b0..f01ebf76 100644 --- a/externallib.php +++ b/externallib.php @@ -125,4 +125,141 @@ public static function submit_mumieduedate_form($contextid, $jsonformdata) { public static function submit_mumieduedate_form_returns() { return new external_value(PARAM_INT, 'duedate id'); } + + /** + * Describes the parameters for create_multiple_tasks webservice. + * @return external_function_parameters + */ + public static function create_multiple_tasks_parameters() { + return new external_function_parameters([ + 'contextid' => new external_value(PARAM_INT, 'Context id of the course'), + 'section' => new external_value(PARAM_INT, 'Section number to add tasks to'), + 'tasks' => new external_value(PARAM_RAW, 'JSON array of task objects'), + 'formdata' => new external_value(PARAM_RAW, 'URL-encoded form data for settings'), + ]); + } + + /** + * Create multiple MUMIE tasks at once with shared settings. + * + * @param int $contextid Course context id + * @param int $section Section number + * @param string $tasks JSON array of task objects + * @param string $formdata URL-encoded serialized form data + * @return array Array of created course module ids + */ + public static function create_multiple_tasks($contextid, $section, $tasks, $formdata) { + global $CFG, $DB; + + require_once($CFG->dirroot . '/course/modlib.php'); + require_once($CFG->dirroot . '/mod/mumie/lib.php'); + require_once($CFG->dirroot . '/mod/mumie/locallib.php'); + + $params = self::validate_parameters( + self::create_multiple_tasks_parameters(), + [ + 'contextid' => $contextid, + 'section' => $section, + 'tasks' => $tasks, + 'formdata' => $formdata, + ] + ); + + $context = context::instance_by_id($params['contextid'], MUST_EXIST); + self::validate_context($context); + require_capability('mod/mumie:addinstance', $context); + + $course = $DB->get_record('course', ['id' => $context->instanceid], '*', MUST_EXIST); + $mumiemodule = $DB->get_record('modules', ['name' => 'mumie'], '*', MUST_EXIST); + $taskarray = json_decode($params['tasks'], true); + if (!is_array($taskarray) || empty($taskarray)) { + throw new invalid_parameter_exception('tasks must be a non-empty JSON array'); + } + if (count($taskarray) > 50) { + throw new invalid_parameter_exception('Cannot create more than 50 tasks at once'); + } + + $formfields = []; + parse_str($params['formdata'], $formfields); + + $points = (int)($formfields['points'] ?? 100); + $gradepass = (float)($formfields['gradepass'] ?? 0); + $gradecat = (int)($formfields['gradecat'] ?? 0); + $launchcontainer = (int)($formfields['launchcontainer'] ?? 0); + $privategradepool = (int)(isset($formfields['privategradepool']) ? $formfields['privategradepool'] : 0); + $completionpass = (int)(isset($formfields['completionpass']) ? $formfields['completionpass'] : 0); + $completionview = (int)($formfields['completionview'] ?? 0); + $isgraded = (int)($formfields['mumie_isgraded'] ?? 1); + $durationselector = $formfields['duration_selector'] ?? 'unlimited'; + + $duedate = 0; + if ($durationselector === 'duedate' && !empty($formfields['duedate']['year'])) { + $duedate = make_timestamp( + $formfields['duedate']['year'], + $formfields['duedate']['month'], + $formfields['duedate']['day'], + $formfields['duedate']['hour'] ?? 0, + $formfields['duedate']['minute'] ?? 0 + ); + } + + $timelimit = 0; + if ($durationselector === 'timelimit' && !empty($formfields['timelimit']['timeunit'])) { + $timelimit = (int)$formfields['timelimit']['number'] * (int)$formfields['timelimit']['timeunit']; + } + + $createdids = []; + foreach ($taskarray as $taskdata) { + $moduleinfo = new stdClass(); + $moduleinfo->modulename = 'mumie'; + $moduleinfo->module = $mumiemodule->id; + $moduleinfo->course = $course->id; + $moduleinfo->section = $params['section']; + $moduleinfo->visible = 1; + $moduleinfo->intro = ''; + $moduleinfo->introformat = FORMAT_HTML; + + $tasklink = clean_param($taskdata['link'] ?? '', PARAM_TEXT); + $taskserver = clean_param($taskdata['server'] ?? '', PARAM_URL); + if (empty($tasklink) || empty($taskserver)) { + throw new invalid_parameter_exception('Each task must have a valid link and server'); + } + + $moduleinfo->name = clean_param($taskdata['name'] ?? '', PARAM_TEXT); + $moduleinfo->taskurl = $tasklink; + $moduleinfo->language = clean_param($taskdata['language'] ?? '', PARAM_TEXT); + $moduleinfo->mumie_coursefile = clean_param($taskdata['path_to_coursefile'] ?? '', PARAM_TEXT); + $moduleinfo->mumie_course = clean_param($taskdata['course'] ?? '', PARAM_TEXT); + $moduleinfo->server = $taskserver; + + $moduleinfo->points = $points; + $moduleinfo->launchcontainer = $launchcontainer; + $moduleinfo->privategradepool = $privategradepool; + $moduleinfo->completionpass = $completionpass; + $moduleinfo->duration_selector = $durationselector; + $moduleinfo->duedate = $duedate; + $moduleinfo->timelimit = $timelimit; + $moduleinfo->isgraded = $isgraded; + + $moduleinfo->grade = $points; + $moduleinfo->gradepass = $gradepass; + $moduleinfo->gradecat = $gradecat; + $moduleinfo->completionview = $completionview; + + $moduleinfo = add_moduleinfo($moduleinfo, $course); + $createdids[] = $moduleinfo->coursemodule; + } + + return $createdids; + } + + /** + * Describes the return value for create_multiple_tasks webservice. + * @return external_multiple_structure + */ + public static function create_multiple_tasks_returns() { + return new external_multiple_structure( + new external_value(PARAM_INT, 'course module id') + ); + } } diff --git a/mod_form.php b/mod_form.php index d05b9792..07208504 100644 --- a/mod_form.php +++ b/mod_form.php @@ -149,6 +149,9 @@ private function add_general_fields(MoodleQuickForm $mform, $serveroptions): voi ) ); $mform->addElement('button', 'multi_problem_selector_btn', get_string('mumie_form_multi_prb_selector_btn', 'mod_mumie')); + $mform->addElement('html', ''); + $mform->addElement('hidden', 'mumie_multi_tasks', ''); + $mform->setType('mumie_multi_tasks', PARAM_RAW); $launchoptions = []; $launchoptions[MUMIE_LAUNCH_CONTAINER_EMBEDDED] = get_string("mumie_form_activity_container_embedded", "mod_mumie"); From 97fa8c82a767735c0ba66a8f8fff491e66210a10 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 3 Jun 2026 12:12:56 +0200 Subject: [PATCH 050/101] update info text, fix bug with worksheets withc deadline and cnacle --- amd/build/mod_form.min.js | 2 +- amd/src/mod_form.js | 103 ++++++++++++++++++++++++++++++++++++-- lang/de/mumie.php | 2 +- lang/en/mumie.php | 2 +- 4 files changed, 103 insertions(+), 6 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 2163d3bc..4502a859 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return void function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const names=tasks.map((t=>t.name)).join(", ");summary.textContent=tasks.length+" tasks selected: "+names,summary.style.display="block"}document.getElementById("id_name").disabled=!0,sendSuccess(),window.focus()}(importObj);const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0,problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&gradingType=all&origin="+encodeURIComponent(window.location.origin)+"&multiSelect=true","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formdata=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[k,v]=_ref2;return encodeURIComponent(k)+"="+encodeURIComponent(v)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formdata}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");form&&form.addEventListener("submit",(function(e){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&tasksField.value&&(e.preventDefault(),problemSelectorController.submitMultiTasks())}))}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return void function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const items=tasks.map((t=>{const li=document.createElement("li");return li.textContent=t.name,li}));summary.innerHTML="";const label=document.createElement("div");label.textContent=tasks.length+" tasks selected:";const list=document.createElement("ul");list.style.margin="0.3em 0 0 1.2em",items.forEach((li=>list.appendChild(li))),summary.appendChild(label),summary.appendChild(list),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameItem=document.getElementById("fitem_id_name");nameItem&&nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((el=>{el.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none"),sendSuccess(),window.focus()}(importObj);const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0,problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&gradingType=all&origin="+encodeURIComponent(window.location.origin)+"&multiSelect=true","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,errorKey=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _config$configuration,_config$configuration2;if(!task.worksheet)continue;const config="string"==typeof task.worksheet?JSON.parse(task.worksheet):task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==config||null===(_config$configuration=config.configuration)||void 0===_config$configuration||null===(_config$configuration2=_config$configuration.correction)||void 0===_config$configuration2?void 0:_config$configuration2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(errorKey)return void require(["core/str"],(function(Str){Str.get_string(errorKey,"mod_mumie").then((function(msg){const field=document.getElementById("id_duration_selector"),fitem=field&&field.closest(".fitem");if(fitem){fitem.classList.add("has-danger");const feedback=fitem.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=msg,feedback.style.display="block");const section=fitem.closest(".collapse:not(.show)");if(section){section.classList.add("show");const btn=document.querySelector('[aria-controls="'+section.id+'"]');btn&&btn.setAttribute("aria-expanded","true")}}field&&(field.scrollIntoView({behavior:"smooth",block:"center"}),field.focus())}))}));const fitemClear=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(fitemClear){fitemClear.classList.remove("has-danger");const fb=fitemClear.querySelector(".form-control-feedback");fb&&(fb.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formdata=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[k,v]=_ref2;return encodeURIComponent(k)+"="+encodeURIComponent(v)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formdata}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){if(cancelClicked)return void(cancelClicked=!1);const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&tasksField.value&&(e.preventDefault(),problemSelectorController.submitMultiTasks())}))}}}})); //# sourceMappingURL=mod_form.min.js.map \ No newline at end of file diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 4c5832de..f2dd54ce 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -171,21 +171,107 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv tasksField.value = JSON.stringify(tasks); } if (summary) { - const names = tasks.map(t => t.name).join(', '); - summary.textContent = tasks.length + ' tasks selected: ' + names; + const items = tasks.map(t => { + const li = document.createElement('li'); + li.textContent = t.name; + return li; + }); + summary.innerHTML = ''; + const label = document.createElement('div'); + label.textContent = tasks.length + ' tasks selected:'; + const list = document.createElement('ul'); + list.style.margin = '0.3em 0 0 1.2em'; + items.forEach(li => list.appendChild(li)); + summary.appendChild(label); + summary.appendChild(list); summary.style.display = 'block'; } - document.getElementById('id_name').disabled = true; + const nameField = document.getElementById('id_name'); + nameField.disabled = true; + nameField.removeAttribute('required'); + const nameItem = document.getElementById('fitem_id_name'); + if (nameItem) { + nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]') + .forEach(el => { el.style.display = 'none'; }); + } + const requiredLegend = document.querySelector('.fdescription.required'); + if (requiredLegend) { + requiredLegend.style.display = 'none'; + } sendSuccess(); window.focus(); } + /** + * Validate worksheet deadline requirements against current duration_selector. + * Returns a lang string key if invalid, null if valid. + * @param {Array} tasks + * @returns {string|null} + */ + function validateWorksheetDeadlines(tasks) { + const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited'; + const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit'; + for (const task of tasks) { + if (!task.worksheet) { + continue; + } + const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet; + const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE'; + if (triggerAfterDeadline && !hasDeadline) { + return 'mumie_form_deadline_required_for_trigger_after_deadline'; + } + if (!triggerAfterDeadline && hasDeadline) { + return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'; + } + } + return null; + } + /** * Submit multi-tasks via AJAX using current form settings, then redirect to course. */ function submitMultiTasks() { const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; const courseId = document.getElementsByName('course')[0]?.value; + const tasks = JSON.parse(tasksField.value); + const errorKey = validateWorksheetDeadlines(tasks); + if (errorKey) { + require(['core/str'], function(Str) { + Str.get_string(errorKey, 'mod_mumie').then(function(msg) { + const field = document.getElementById('id_duration_selector'); + const fitem = field && field.closest('.fitem'); + if (fitem) { + fitem.classList.add('has-danger'); + const feedback = fitem.querySelector('.form-control-feedback'); + if (feedback) { + feedback.innerHTML = msg; + feedback.style.display = 'block'; + } + const section = fitem.closest('.collapse:not(.show)'); + if (section) { + section.classList.add('show'); + const btn = document.querySelector('[aria-controls="' + section.id + '"]'); + if (btn) { + btn.setAttribute('aria-expanded', 'true'); + } + } + } + if (field) { + field.scrollIntoView({behavior: 'smooth', block: 'center'}); + field.focus(); + } + }); + }); + return; + } + const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem'); + if (fitemClear) { + fitemClear.classList.remove('has-danger'); + const fb = fitemClear.querySelector('.form-control-feedback'); + if (fb) { + fb.style.display = 'none'; + } + } const settings = collectFormSettings(); settings.tasks = tasksField.value; @@ -635,7 +721,18 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv const submitBtn = document.getElementById('id_submitbutton'); const form = submitBtn && submitBtn.closest('form'); if (form) { + let cancelClicked = false; + const cancelBtn = document.getElementById('id_cancel'); + if (cancelBtn) { + cancelBtn.addEventListener('click', function() { + cancelClicked = true; + }); + } form.addEventListener('submit', function(e) { + if (cancelClicked) { + cancelClicked = false; + return; + } const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; if (tasksField && tasksField.value) { e.preventDefault(); diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 74316374..2e38082a 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -126,7 +126,7 @@ $string['mumie_grade_overridden'] = 'Bewertung erfolgreich gespeichert!'; $string['mumie_grade_percentage'] = 'Bewerung in %'; $string['mumie_grading_settings'] = "Individuelle Bewertungseinstellungen"; -$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'; +$string['mumie_multi_problem_selector'] = 'Alternativ können Sie mit der Mehrfach-Aufgabenauswahl auch mehrere MUMIE-Aufgaben auf einmal auswählen. Alle Aufgaben werden mit den eingestellten Einstellungen angelegt (Punkte, Frist, Startcontainer etc.). Jede Aufgabe behält ihren eigenen Namen — anders als bei der Einzelauswahl kann kein eigener Name vergeben werden.

Weitere Informationen finden Sie in unserem Wiki'; $string['mumie_no_other_task_found'] = 'Keine andere MUMIE Tasks in Kurs gefunden'; $string['mumie_no_submissions'] = 'Keine Antworten abgegeben'; $string['mumie_open_task'] = 'MUMIE-Task öffnen'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 518b89d6..5628402a 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -121,7 +121,7 @@ $string['mumie_grade_overridden'] = 'Updated grade successfully!'; $string['mumie_grade_percentage'] = 'Grade in %'; $string['mumie_grading_settings'] = "Individual grading settings"; -$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'; +$string['mumie_multi_problem_selector'] = 'Alternatively, you can also create multiple MUMIE Tasks at once using the Multi Problem Selector. All tasks will be created with the settings configured (points, deadline, container type, etc.). Each task keeps its own name — unlike single task creation, no custom name can be assigned.

For more information, have a look at our wiki'; $string['mumie_no_other_task_found'] = 'No other MUMIE Tasks found in course'; $string['mumie_no_submissions'] = 'No answers submitted'; $string['mumie_open_task'] = 'Open MUMIE Task'; From be18330d0af29721fb7bc5877dde09fb76c07b7b Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 3 Jun 2026 15:26:51 +0200 Subject: [PATCH 051/101] remove dead DnD Code --- amd/build/mod_form.min.js.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amd/build/mod_form.min.js.map b/amd/build/mod_form.min.js.map index 4d098c15..5d5497f7 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formdata = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formdata,\n };\n }\n\n /**\n * Handle multi-select postMessage: store tasks and show summary so teacher can adjust settings.\n * @param {Array} tasks array of task objects from the selector\n */\n function handleMultiSelect(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const names = tasks.map(t => t.name).join(', ');\n summary.textContent = tasks.length + ' tasks selected: ' + names;\n summary.style.display = 'block';\n }\n document.getElementById('id_name').disabled = true;\n sendSuccess();\n window.focus();\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\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\n if (Array.isArray(importObj)) {\n handleMultiSelect(importObj);\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n problemSelectorWindow = window.open(\n lmsSelectorUrl +\n '/lms-problem-selector?' +\n \"serverUrl=\" +\n encodeURIComponent(serverController.getSelectedServer().urlprefix) +\n '&gradingType=all' +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&multiSelect=true',\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n submitMultiTasks: submitMultiTasks,\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n form.addEventListener('submit', function(e) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField && tasksField.value) {\n e.preventDefault();\n problemSelectorController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","tasks","tasksField","summary","names","map","t","join","textContent","length","focus","handleMultiSelect","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","submitMultiTasks","courseId","_document$getElements","settings","section","parseInt","URLSearchParams","search","get","submitBtn","form","closest","sensitiveFields","formdata","from","FormData","filter","_ref","key","includes","_ref2","k","v","contextid","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","forEach","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formdata = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formdata,\n };\n }\n\n /**\n * Handle multi-select postMessage: store tasks and show summary so teacher can adjust settings.\n * @param {Array} tasks array of task objects from the selector\n */\n function handleMultiSelect(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const items = tasks.map(t => {\n const li = document.createElement('li');\n li.textContent = t.name;\n return li;\n });\n summary.innerHTML = '';\n const label = document.createElement('div');\n label.textContent = tasks.length + ' tasks selected:';\n const list = document.createElement('ul');\n list.style.margin = '0.3em 0 0 1.2em';\n items.forEach(li => list.appendChild(li));\n summary.appendChild(label);\n summary.appendChild(list);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameItem = document.getElementById('fitem_id_name');\n if (nameItem) {\n nameItem.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(el => { el.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n sendSuccess();\n window.focus();\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet;\n const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const errorKey = validateWorksheetDeadlines(tasks);\n if (errorKey) {\n require(['core/str'], function(Str) {\n Str.get_string(errorKey, 'mod_mumie').then(function(msg) {\n const field = document.getElementById('id_duration_selector');\n const fitem = field && field.closest('.fitem');\n if (fitem) {\n fitem.classList.add('has-danger');\n const feedback = fitem.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = msg;\n feedback.style.display = 'block';\n }\n const section = fitem.closest('.collapse:not(.show)');\n if (section) {\n section.classList.add('show');\n const btn = document.querySelector('[aria-controls=\"' + section.id + '\"]');\n if (btn) {\n btn.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (field) {\n field.scrollIntoView({behavior: 'smooth', block: 'center'});\n field.focus();\n }\n });\n });\n return;\n }\n const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (fitemClear) {\n fitemClear.classList.remove('has-danger');\n const fb = fitemClear.querySelector('.form-control-feedback');\n if (fb) {\n fb.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\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\n if (Array.isArray(importObj)) {\n handleMultiSelect(importObj);\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n problemSelectorWindow = window.open(\n lmsSelectorUrl +\n '/lms-problem-selector?' +\n \"serverUrl=\" +\n encodeURIComponent(serverController.getSelectedServer().urlprefix) +\n '&gradingType=all' +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&multiSelect=true',\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n submitMultiTasks: submitMultiTasks,\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField && tasksField.value) {\n e.preventDefault();\n problemSelectorController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","tasks","tasksField","summary","items","map","t","li","createElement","textContent","innerHTML","label","length","list","margin","forEach","appendChild","nameField","nameItem","querySelectorAll","el","requiredLegend","querySelector","focus","handleMultiSelect","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","submitMultiTasks","courseId","_document$getElements","errorKey","hasDeadline","task","config","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","msg","field","fitem","closest","classList","add","feedback","section","btn","id","scrollIntoView","behavior","block","fitemClear","_document$getElementB2","remove","fb","settings","parseInt","URLSearchParams","search","get","submitBtn","form","sensitiveFields","formdata","from","FormData","filter","_ref","key","includes","_ref2","k","v","join","contextid","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelBtn"],"mappings":"AAAAA,4BAAO,CAAC,SAAU,iBAAkB,qBAAsB,iCAAkC,cACxF,iBACUC,gBAAkBC,SAASC,eAAe,wBAC1CC,cAAgBF,SAASG,kBAAkB,wBAAwB,OACrEC,eACAC,eACAC,gBAGEC,mBAAsB,iBAElBC,iBAAmBR,SAASC,eAAe,wBAC3CQ,WAAaT,SAASC,eAAe,8BAKlCS,mBACuB,MAArBD,WAAWE,eAMbC,yBACYF,cAEbF,iBAAiBK,aAAa,WAAY,YAC1CL,iBAAiBG,MAAQ,aAEzBH,iBAAiBM,gBAAgB,YAKN,cAA3BN,iBAAiBG,OACjBX,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,sBAAsBc,MAAMC,QALpC,OAMhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QANzC,OAOhBhB,SAASC,eAAe,oBAAoBc,MAAMC,QAPlC,OAQhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QARvC,QASkB,YAA3BR,iBAAiBG,OACxBX,SAASC,eAAe,oBAAoBc,MAAMC,QAAU,GAC5DhB,SAASC,eAAe,yBAAyBc,MAAMC,QAAU,GAEjEhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAbzC,OAchBhB,SAASC,eAAe,sBAAsBc,MAAMC,QAdpC,OAehBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAfzC,QAgBkB,cAA3BR,iBAAiBG,QACxBX,SAASC,eAAe,sBAAsBc,MAAMC,QAAU,GAC9DhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,oBAAoBc,MAAMC,QApBlC,OAqBhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QArBvC,OAsBhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAtBzC,cA0BjB,CACHC,KAAM,WACFT,iBAAiBU,SAAW,WACxBN,0BAEJO,OAAOC,iBAAiB,QAAQ,KAC5BR,4BAEJA,0BAEJS,oBAAqBT,uBACrBF,WAAYA,WACZY,mBAAoB,SAASC,UACzBd,WAAWE,MAAQY,SAAW,IAAM,KAExCC,mBAAoB,kBACTf,WAAWE,QAlEF,GAuEtBc,iBAAoB,eAClBC,sBACEC,eAAiB3B,SAASC,eAAe,mBAExC,CACHgB,KAAM,SAASW,WACXF,gBAAkBE,WAEtBC,kBAAmB,iBACTC,mBAAqBH,eAAeI,QAAQJ,eAAeK,eAAeC,YACzEP,gBAAgBQ,MAAKC,QAAUA,OAAOC,OAASN,sBAE1DO,QAAS,WACLV,eAAeW,UAAW,WAgpBZC,WACfA,KAAKC,YACRD,KAAKE,YAAYF,KAAKC,YAjpBlBE,CAAiBf,kBAdH,GAmBpBgB,0BAA6B,iBACzBC,sBAAwB5C,SAASC,eAAe,uBAChD4C,2BAA6B7C,SAASC,eAAe,qCACvD6C,4BACEC,SAAW/C,SAASG,kBAAkB,aAAa,GAAGQ,eAQnDqC,aAAaC,UACbH,uBAGLA,sBAAsBI,YAAYC,KAAKC,UAAUH,UAAW7C,yBAOvDiD,kBAAYC,+DAAU,GAC3BN,aAAa,CACTO,SAAS,EACTD,QAASA,mBAqKRE,qBACLrC,OAAOC,iBAAiB,WAAYqC,oCAC5BA,MAAMC,SAAWtD,4BAGfuD,UAAYR,KAAKS,MAAMH,MAAMI,SAE/BC,MAAMC,QAAQJ,gCAnICK,aACjBC,WAAajE,SAASG,kBAAkB,qBAAqB,GAC7D+D,QAAUlE,SAASC,eAAe,gCACpCgE,aACAA,WAAWtD,MAAQwC,KAAKC,UAAUY,QAElCE,QAAS,OACHC,MAAQH,MAAMI,KAAIC,UACdC,GAAKtE,SAASuE,cAAc,aAClCD,GAAGE,YAAcH,EAAEjC,KACZkC,MAEXJ,QAAQO,UAAY,SACdC,MAAQ1E,SAASuE,cAAc,OACrCG,MAAMF,YAAcR,MAAMW,OAAS,yBAC7BC,KAAO5E,SAASuE,cAAc,MACpCK,KAAK7D,MAAM8D,OAAS,kBACpBV,MAAMW,SAAQR,IAAMM,KAAKG,YAAYT,MACrCJ,QAAQa,YAAYL,OACpBR,QAAQa,YAAYH,MACpBV,QAAQnD,MAAMC,QAAU,cAEtBgE,UAAYhF,SAASC,eAAe,WAC1C+E,UAAU1C,UAAW,EACrB0C,UAAUlE,gBAAgB,kBACpBmE,SAAWjF,SAASC,eAAe,iBACrCgF,UACAA,SAASC,iBAAiB,gDACrBJ,SAAQK,KAAQA,GAAGpE,MAAMC,QAAU,gBAEtCoE,eAAiBpF,SAASqF,cAAc,0BAC1CD,iBACAA,eAAerE,MAAMC,QAAU,QAEnCqC,cACAlC,OAAOmE,QAiGCC,CAAkB5B,iBAIhBpC,UAAkC,IAAvBoC,UAAUpC,SACrBiE,uCAAY7B,UAAU6B,+DAAa,SAErCC,iBAAiBC,UAAU/B,UAAUgC,oBACrCC,eAAeC,YAAYlC,UAAUmC,UACrCC,eAAeC,aAAarC,UAAUsC,KAAMtC,UAAUmC,SAAUnC,UAAUvB,MAC1E2D,eAAeG,YAAY3E,UAC3B4E,oBAAoBC,aAAaZ,WACjCnC,cACAlC,OAAOmE,QAYfe,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN,+BACPC,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBtD,QAASqD,EAAE,GACXE,KAAM,YAEXC,KAAKP,aAAaQ,cAnBnB,MAAOC,mBAnLbhE,aAAa,CACTO,SAAS,EACTD,+DAHuB,KAqLnB2D,CAAYD,MAAM1D,aAEvB,YAwBE4D,iBACCC,YAAcpB,eAAeqB,iBAC7BC,UAAYtB,eAAeuB,yBAC3BC,eAAiB9F,iBAAiBI,oBAAoB2F,cAwCtBC,yBAAAA,kBAvCMF,eAwCrC,IAAIG,IAxCiBtH,gBAwCOsD,SAAW,IAAIgE,IAAID,mBAAmB/D,QAtC9D,wCAEHX,SACA,cACA4E,mBAAmBJ,gBACnB,gBACA3B,eAAegC,sBACf,WAAaD,mBAAmBxG,OAAO0G,SAASnE,QAChD,gBAAkByD,YAClB,cAAgB7G,WACf+G,UAAY,cAAgBA,UAAY,IAE1CjH,eAAAA,6BAGH2C,SACA,cACA4E,mBAAmBJ,gBACnB,gBACA3B,eAAegC,sBACf,WAAaD,mBAAmBxG,OAAO0G,SAASnE,QAChD,WAAarD,eACb,gBAAkB8G,YAVf/G,oCAaFiH,UAAY,cAAgBA,UAAY,UAgB1C,CACHpG,KAAM,WACF2B,sBAAsBkF,QAAU,WAC5BhF,sBAAwB3B,OAAO4G,KAAKb,WAAY,WAGpD/F,OAAO6G,QAAU,WACb3E,eAGJlC,OAAOC,iBAAiB,gBAAgB,WACpCiC,iBACD,GAEHG,qBAEAX,2BAA2BiF,QAAU,SAASG,GAC1CA,EAAEC,iBACFlI,SAASC,eAAe,WAAWqC,UAAW,EAC9CQ,sBAAwB3B,OAAO4G,KAC3B3H,eAAAA,mCAGAuH,mBAAmBlG,iBAAiBI,oBAAoB2F,WAHxDpH,2BAKauH,mBAAmBxG,OAAO0G,SAASnE,QAChD,oBACA,SACA,oCAIZrB,QAAS,WACLO,sBAAsBN,UAAW,GAErC6F,mFA7LMlE,WAAajE,SAASG,kBAAkB,qBAAqB,GAC7DiI,uCAAWpI,SAASG,kBAAkB,UAAU,2CAArCkI,sBAAyC1H,MAEpD2H,kBA1B0BtE,uCAC1BxD,gDAAmBR,SAASC,eAAe,sFAAyBU,QAAS,YAC7E4H,YAAmC,YAArB/H,kBAAuD,cAArBA,qBACjD,MAAMgI,QAAQxE,MAAO,sDACjBwE,KAAKhD,yBAGJiD,OAAmC,iBAAnBD,KAAKhD,UAAyBrC,KAAKS,MAAM4E,KAAKhD,WAAagD,KAAKhD,UAChFkD,qBAA4E,oBAArDD,MAAAA,sCAAAA,OAAQE,qGAAeC,2EAAYC,kBAC5DH,uBAAyBH,kBAClB,8DAENG,sBAAwBH,kBAClB,qFAGR,KAUUO,CADH3F,KAAKS,MAAMK,WAAWtD,WAEhC2H,qBACAjC,QAAQ,CAAC,aAAa,SAAS0C,KAC3BA,IAAIC,WAAWV,SAAU,aAAaW,MAAK,SAASC,WAC1CC,MAAQnJ,SAASC,eAAe,wBAChCmJ,MAAQD,OAASA,MAAME,QAAQ,aACjCD,MAAO,CACPA,MAAME,UAAUC,IAAI,oBACdC,SAAWJ,MAAM/D,cAAc,0BACjCmE,WACAA,SAAS/E,UAAYyE,IACrBM,SAASzI,MAAMC,QAAU,eAEvByI,QAAUL,MAAMC,QAAQ,2BAC1BI,QAAS,CACTA,QAAQH,UAAUC,IAAI,cAChBG,IAAM1J,SAASqF,cAAc,mBAAqBoE,QAAQE,GAAK,MACjED,KACAA,IAAI7I,aAAa,gBAAiB,SAI1CsI,QACAA,MAAMS,eAAe,CAACC,SAAU,SAAUC,MAAO,WACjDX,MAAM7D,qBAMhByE,0CAAa/J,SAASC,eAAe,iEAAxB+J,uBAAiDX,QAAQ,aACxEU,WAAY,CACZA,WAAWT,UAAUW,OAAO,oBACtBC,GAAKH,WAAW1E,cAAc,0BAChC6E,KACAA,GAAGnJ,MAAMC,QAAU,cAGrBmJ,0BAjIAV,QAAUW,SAAS,IAAIC,gBAAgBlJ,OAAO0G,SAASyC,QAAQC,IAAI,YAAc,GACjFC,UAAYxK,SAASC,eAAe,mBACpCwK,KAAOD,WAAaA,UAAUnB,QAAQ,QACtCqB,gBAAkB,CAAC,UAAW,2BAC9BC,SAAWF,KACX3G,MAAM8G,KAAK,IAAIC,SAASJ,OACrBK,QAAOC,WAAEC,iBAAUN,gBAAgBO,SAASD,QAC5C5G,KAAI8G,YAAEC,EAAGC,gBAAOzD,mBAAmBwD,GAAK,IAAMxD,mBAAmByD,MACjEC,KAAK,KACR,SACC,CACHC,UAAWlB,SAAS9J,WACpBmJ,QAASA,QACTkB,SAAUA,UAoHGY,GACjBpB,SAASnG,MAAQC,WAAWtD,MAE5B0F,QAAQ,CAAC,YAAa,sBAAsB,SAASmF,KAAMC,cACvDD,KAAKE,KAAK,CAAC,CACPC,WAAY,kCACZC,KAAMzB,YACN,GAAGzD,MAAK,WACRvF,OAAO0G,SAASgE,KAAOC,EAAEC,IAAIC,QAAU,uBAAyB5D,YACjEtB,KAAK2E,aAAa1E,gBAxLE,GAuU7BtB,iBAAoB,iBAChBwG,eAAiBjM,SAASC,eAAe,mBACzCiM,eAAiBlM,SAASG,kBAAkB,oBAAoB,YAgB7DgM,mDACCC,eAAiB3G,iBAAiB4G,oBAClCC,iBAAmB1G,eAAegC,sBACnCwE,gBAAmBE,mBAGxBL,eAAetL,oCAAQyL,eAAehK,KACjCF,MAAKqK,aAAeA,YAAYzG,WAAawG,2DAD3BE,sBAC8C7L,aAGlE,CACHM,KAAM,WACFkL,oBAEJE,kBAAmB,kBACC5K,iBAAiBI,oBAAoB4K,QACtCvK,MAAKwK,QAAUA,OAAOC,aAAeT,eAAevL,SAEvE+E,UAAW,SAASkH,gBA1BMD,WAAAA,WA2BDC,WA1BzBV,eAAevL,MAAQgM,WACvBR,qBAZkB,GA0CpBvG,eAAkB,iBACdiH,aAAe7M,SAASC,eAAe,qBACtC,CACH2H,oBAAqB,kBACViF,aAAalM,OAExBkF,YAAa,SAASiH,MAClBD,aAAalM,MAAQmM,OAPT,GAYlB/G,eAAkB,iBACdgH,mBAAqB/M,SAASG,kBAAkB,WAAW,GAC3D6M,SAAWhN,SAASC,eAAe,WACnCgN,mBAAqBjN,SAASC,eAAe,oCAc1CiN,yBAAyBC,eAC9BF,mBAAmBtM,MAAQwM,uBAQtBC,cAAcnH,KAAMH,gBACnBqH,uBAWYlH,KAAMH,iBACjBG,KAnCuB,SAmCYH,SAZpBuH,CAAapH,KAAMH,UACzCiH,mBAAmBpM,MAAQwM,cAC3BD,yBAAyBC,qBAoCtB,CACHlM,KAAM,WACFiM,yBAAyBH,mBAAmBpM,QAEhDqF,aAAc,SAASC,KAAMH,SAAU1D,MACnCgL,cAAcnH,KAAMH,mBA5DR1D,MAChB4K,SAASrM,MAAQyB,KA4DbkL,CAAWlL,OAEf8D,YAAa,SAAS3E,UAClBhB,mBAAmBe,mBAAmBC,2BAhBpCe,SAAW/B,mBAAmBG,aACpCV,SAASC,eAAe,aAAaqC,SAAWA,SAChDtC,SAASC,eAAe,gBAAgBqC,SAAWA,SACnDtC,SAASC,eAAe,eAAeqC,SAAWA,SAClD/B,mBAAmBc,sBAafkM,IAEJnG,eAAgB,iBACN7F,SAAWhB,mBAAmBiB,2BACnB,MAAbD,SACO,SACa,MAAbA,SACA,WAEJ,OAEX+F,uBAAwB,kBAvCJrB,KAwCM8G,mBAAmBpM,OAvCpCsK,SA5CqB,UA6CnBhF,KAAKuH,MA7Cc,UA6CmB,GAE1CvH,SAJaA,OA/CJ,GA6FlBwH,wBAA2B,iBACvBC,wBAA0B1N,SAASG,kBAAkB,6BACrDwN,uBAAyB3N,SAASG,kBAAkB,kCAAkC,OACxFyN,iBAAmB,SACjBC,oBAAsB7N,SAASG,kBAAkB,yBACjD2N,cAAgB9N,SAASG,kBAAkB,wBAAwB,OACrE4N,gBAAkB,SAChBC,cAAgBhO,SAASG,kBAAkB,kCAwE1C,CACHc,KAAM,WAvDN4M,oBAAoB/I,SAAQ,SAASmJ,UACjCA,SAAS/M,SAAW,WACX+M,SAASC,QAGVH,gBAAgBI,KAAKF,SAAStN,OAF9BoN,gBAAkBA,gBAAgBjD,QAAOvI,MAAQA,OAAS0L,SAAStN,QAIvEmN,cAAcnN,MAAQwC,KAAKC,UAAU2K,qBAS7CL,wBAAwB5I,SAAQ,SAASmJ,UACrCA,SAAS/M,SAAW,WACX+M,SAASC,QAGVN,iBAAiBO,KAAKF,SAAStN,OAF/BiN,iBAAmBA,iBAAiB9C,QAAOvI,MAAQA,OAAS0L,SAAStN,QAIzEgN,uBAAuBhN,MAAQwC,KAAKC,UAAUwK,sBAStDI,cAAclJ,SAAQ,SAASsJ,iBAC3BA,gBAAgBlN,SAAW,WAClBkN,gBAAgBF,QAQjBL,oBAAoB/I,SAAQ,SAASuJ,kBApD5BC,MAAOC,QAqDRF,aAAaG,aAAa,aAAeJ,gBAAgBzN,QACzD0N,aAAaH,SAAU,EAtDtBI,MAuDeP,gBAvDRQ,QAuDyBF,aAAa1N,MAtD7D2N,MAAMrD,SAASsD,UAChBD,MAAMH,KAAKI,aA2CHV,oBAAoB/I,SAAQ,SAASuJ,cAC7BA,aAAaG,aAAa,aAAeJ,gBAAgBzN,QACzD0N,aAAaH,SAAU,EACvBH,gBAAkBA,gBAAgBjD,QAAOvI,MAAQ8L,aAAa1N,QAAU4B,WAWpFuL,cAAcnN,MAAQwC,KAAKC,UAAU2K,uBA1EpB,GAwF3B5H,oBAAuB,iBACnBsI,iBAAmBzO,SAASC,eAAe,4BAC1C,CACHmG,aAAc,SAASZ,WACfA,UACAiJ,iBAAiB5N,aAAa,QAASsC,KAAKC,UAAUoC,YAEtDiJ,iBAAiB3N,gBAAgB,WAPpB,YAiBpB4N,qBAAqBpG,UAC1BjC,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN8B,SACP7B,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBtD,QAASqD,EAAE,GAAK,MAAQzG,cAAcsO,aAAa,SAAW,OAC9D3H,KAAM,eAEXC,KAAKP,aAAaQ,cAEzBtF,iBAAiBY,UACjBM,0BAA0BN,gBAGvB,CACHpB,KAAM,SAAS0N,eAAgBC,eAAgB9B,MAC3C1M,eAAiBwO,eACjBvO,eAAiByM,KACjBxM,UAAYqO,qBACNE,OAAS7O,SAASC,eAAe,WAAWuO,aAAa,SACzD9M,gBAAkByB,KAAKS,MAAM5D,SAASG,kBAAkB,0BAA0B,GAAGQ,OACvFkO,QA2D+E,KAAhF7O,SAASG,kBAAkB,wBAAwB,GAAGqO,aAAa,SA1DlEE,qBAAqB,6BACbhN,gBAAgBiD,QAGxBlD,iBAAiBR,KAAKS,iBACtB+D,iBAAiBxE,OACjB8E,eAAe9E,OACfwM,wBAAwBxM,OACxB0B,0BAA0B1B,OAC1BV,mBAAmBU,QAPnByN,qBAAqB,6BASzBjB,wBAAwBxM,OACpBlB,iBACAsG,QAAQ,CAAC,mCAAmC,SAASyI,aACjDA,YAAY7N,KAAKlB,gBAAiBO,oBAIpCkK,UAAYxK,SAASC,eAAe,mBACpCwK,KAAOD,WAAaA,UAAUnB,QAAQ,WACxCoB,KAAM,KACFsE,eAAgB,QACdC,UAAYhP,SAASC,eAAe,aACtC+O,WACAA,UAAU5N,iBAAiB,SAAS,WAChC2N,eAAgB,KAGxBtE,KAAKrJ,iBAAiB,UAAU,SAAS6G,MACjC8G,0BACAA,eAAgB,SAGd9K,WAAajE,SAASG,kBAAkB,qBAAqB,GAC/D8D,YAAcA,WAAWtD,QACzBsH,EAAEC,iBACFvF,0BAA0BwF"} \ No newline at end of file From 0ca2dd567ec26e9f6089ff295450e607eeddfc8b Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 3 Jun 2026 17:47:26 +0200 Subject: [PATCH 052/101] add SSO for multi seelct --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 33 ++++++++++++++++++++++----------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 4502a859..9c25f17f 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return void function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const items=tasks.map((t=>{const li=document.createElement("li");return li.textContent=t.name,li}));summary.innerHTML="";const label=document.createElement("div");label.textContent=tasks.length+" tasks selected:";const list=document.createElement("ul");list.style.margin="0.3em 0 0 1.2em",items.forEach((li=>list.appendChild(li))),summary.appendChild(label),summary.appendChild(list),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameItem=document.getElementById("fitem_id_name");nameItem&&nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((el=>{el.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none"),sendSuccess(),window.focus()}(importObj);const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0,problemSelectorWindow=window.open(lmsSelectorUrl+"/lms-problem-selector?serverUrl="+encodeURIComponent(serverController.getSelectedServer().urlprefix)+"&gradingType=all&origin="+encodeURIComponent(window.location.origin)+"&multiSelect=true","_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,errorKey=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _config$configuration,_config$configuration2;if(!task.worksheet)continue;const config="string"==typeof task.worksheet?JSON.parse(task.worksheet):task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==config||null===(_config$configuration=config.configuration)||void 0===_config$configuration||null===(_config$configuration2=_config$configuration.correction)||void 0===_config$configuration2?void 0:_config$configuration2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(errorKey)return void require(["core/str"],(function(Str){Str.get_string(errorKey,"mod_mumie").then((function(msg){const field=document.getElementById("id_duration_selector"),fitem=field&&field.closest(".fitem");if(fitem){fitem.classList.add("has-danger");const feedback=fitem.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=msg,feedback.style.display="block");const section=fitem.closest(".collapse:not(.show)");if(section){section.classList.add("show");const btn=document.querySelector('[aria-controls="'+section.id+'"]');btn&&btn.setAttribute("aria-expanded","true")}}field&&(field.scrollIntoView({behavior:"smooth",block:"center"}),field.focus())}))}));const fitemClear=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(fitemClear){fitemClear.classList.remove("has-danger");const fb=fitemClear.querySelector(".form-control-feedback");fb&&(fb.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formdata=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[k,v]=_ref2;return encodeURIComponent(k)+"="+encodeURIComponent(v)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formdata}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){if(cancelClicked)return void(cancelClicked=!1);const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&tasksField.value&&(e.preventDefault(),problemSelectorController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return void function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const items=tasks.map((t=>{const li=document.createElement("li");return li.textContent=t.name,li}));summary.innerHTML="";const label=document.createElement("div");label.textContent=tasks.length+" tasks selected:";const list=document.createElement("ul");list.style.margin="0.3em 0 0 1.2em",items.forEach((li=>list.appendChild(li))),summary.appendChild(label),summary.appendChild(list),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameItem=document.getElementById("fitem_id_name");nameItem&&nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((el=>{el.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none"),sendSuccess(),window.focus()}(importObj);const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0;const selectedServer=serverController.getSelectedServer().urlprefix,multiUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiUrl,"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,errorKey=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _config$configuration,_config$configuration2;if(!task.worksheet)continue;const config="string"==typeof task.worksheet?JSON.parse(task.worksheet):task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==config||null===(_config$configuration=config.configuration)||void 0===_config$configuration||null===(_config$configuration2=_config$configuration.correction)||void 0===_config$configuration2?void 0:_config$configuration2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(errorKey)return void require(["core/str"],(function(Str){Str.get_string(errorKey,"mod_mumie").then((function(msg){const field=document.getElementById("id_duration_selector"),fitem=field&&field.closest(".fitem");if(fitem){fitem.classList.add("has-danger");const feedback=fitem.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=msg,feedback.style.display="block");const section=fitem.closest(".collapse:not(.show)");if(section){section.classList.add("show");const btn=document.querySelector('[aria-controls="'+section.id+'"]');btn&&btn.setAttribute("aria-expanded","true")}}field&&(field.scrollIntoView({behavior:"smooth",block:"center"}),field.focus())}))}));const fitemClear=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(fitemClear){fitemClear.classList.remove("has-danger");const fb=fitemClear.querySelector(".form-control-feedback");fb&&(fb.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formdata=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[k,v]=_ref2;return encodeURIComponent(k)+"="+encodeURIComponent(v)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formdata}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){if(cancelClicked)return void(cancelClicked=!1);const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&tasksField.value&&(e.preventDefault(),problemSelectorController.submitMultiTasks())}))}}}})); //# 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 5d5497f7..7eaad648 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formdata = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formdata,\n };\n }\n\n /**\n * Handle multi-select postMessage: store tasks and show summary so teacher can adjust settings.\n * @param {Array} tasks array of task objects from the selector\n */\n function handleMultiSelect(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const items = tasks.map(t => {\n const li = document.createElement('li');\n li.textContent = t.name;\n return li;\n });\n summary.innerHTML = '';\n const label = document.createElement('div');\n label.textContent = tasks.length + ' tasks selected:';\n const list = document.createElement('ul');\n list.style.margin = '0.3em 0 0 1.2em';\n items.forEach(li => list.appendChild(li));\n summary.appendChild(label);\n summary.appendChild(list);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameItem = document.getElementById('fitem_id_name');\n if (nameItem) {\n nameItem.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(el => { el.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n sendSuccess();\n window.focus();\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet;\n const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const errorKey = validateWorksheetDeadlines(tasks);\n if (errorKey) {\n require(['core/str'], function(Str) {\n Str.get_string(errorKey, 'mod_mumie').then(function(msg) {\n const field = document.getElementById('id_duration_selector');\n const fitem = field && field.closest('.fitem');\n if (fitem) {\n fitem.classList.add('has-danger');\n const feedback = fitem.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = msg;\n feedback.style.display = 'block';\n }\n const section = fitem.closest('.collapse:not(.show)');\n if (section) {\n section.classList.add('show');\n const btn = document.querySelector('[aria-controls=\"' + section.id + '\"]');\n if (btn) {\n btn.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (field) {\n field.scrollIntoView({behavior: 'smooth', block: 'center'});\n field.focus();\n }\n });\n });\n return;\n }\n const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (fitemClear) {\n fitemClear.classList.remove('has-danger');\n const fb = fitemClear.querySelector('.form-control-feedback');\n if (fb) {\n fb.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\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\n if (Array.isArray(importObj)) {\n handleMultiSelect(importObj);\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n problemSelectorWindow = window.open(\n lmsSelectorUrl +\n '/lms-problem-selector?' +\n \"serverUrl=\" +\n encodeURIComponent(serverController.getSelectedServer().urlprefix) +\n '&gradingType=all' +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&multiSelect=true',\n \"_blank\",\n 'toolbar=0,location=0,menubar=0'\n );\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n submitMultiTasks: submitMultiTasks,\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField && tasksField.value) {\n e.preventDefault();\n problemSelectorController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","tasks","tasksField","summary","items","map","t","li","createElement","textContent","innerHTML","label","length","list","margin","forEach","appendChild","nameField","nameItem","querySelectorAll","el","requiredLegend","querySelector","focus","handleMultiSelect","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","submitMultiTasks","courseId","_document$getElements","errorKey","hasDeadline","task","config","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","msg","field","fitem","closest","classList","add","feedback","section","btn","id","scrollIntoView","behavior","block","fitemClear","_document$getElementB2","remove","fb","settings","parseInt","URLSearchParams","search","get","submitBtn","form","sensitiveFields","formdata","from","FormData","filter","_ref","key","includes","_ref2","k","v","join","contextid","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelBtn"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formdata = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formdata,\n };\n }\n\n /**\n * Handle multi-select postMessage: store tasks and show summary so teacher can adjust settings.\n * @param {Array} tasks array of task objects from the selector\n */\n function handleMultiSelect(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const items = tasks.map(t => {\n const li = document.createElement('li');\n li.textContent = t.name;\n return li;\n });\n summary.innerHTML = '';\n const label = document.createElement('div');\n label.textContent = tasks.length + ' tasks selected:';\n const list = document.createElement('ul');\n list.style.margin = '0.3em 0 0 1.2em';\n items.forEach(li => list.appendChild(li));\n summary.appendChild(label);\n summary.appendChild(list);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameItem = document.getElementById('fitem_id_name');\n if (nameItem) {\n nameItem.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(el => { el.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n sendSuccess();\n window.focus();\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet;\n const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const errorKey = validateWorksheetDeadlines(tasks);\n if (errorKey) {\n require(['core/str'], function(Str) {\n Str.get_string(errorKey, 'mod_mumie').then(function(msg) {\n const field = document.getElementById('id_duration_selector');\n const fitem = field && field.closest('.fitem');\n if (fitem) {\n fitem.classList.add('has-danger');\n const feedback = fitem.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = msg;\n feedback.style.display = 'block';\n }\n const section = fitem.closest('.collapse:not(.show)');\n if (section) {\n section.classList.add('show');\n const btn = document.querySelector('[aria-controls=\"' + section.id + '\"]');\n if (btn) {\n btn.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (field) {\n field.scrollIntoView({behavior: 'smooth', block: 'center'});\n field.focus();\n }\n });\n });\n return;\n }\n const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (fitemClear) {\n fitemClear.classList.remove('has-danger');\n const fb = fitemClear.querySelector('.form-control-feedback');\n if (fb) {\n fb.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\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\n if (Array.isArray(importObj)) {\n handleMultiSelect(importObj);\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n submitMultiTasks: submitMultiTasks,\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField && tasksField.value) {\n e.preventDefault();\n problemSelectorController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","tasks","tasksField","summary","items","map","t","li","createElement","textContent","innerHTML","label","length","list","margin","forEach","appendChild","nameField","nameItem","querySelectorAll","el","requiredLegend","querySelector","focus","handleMultiSelect","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiUrl","submitMultiTasks","courseId","_document$getElements","errorKey","hasDeadline","task","config","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","msg","field","fitem","closest","classList","add","feedback","section","btn","id","scrollIntoView","behavior","block","fitemClear","_document$getElementB2","remove","fb","settings","parseInt","URLSearchParams","search","get","submitBtn","form","sensitiveFields","formdata","from","FormData","filter","_ref","key","includes","_ref2","k","v","join","contextid","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelBtn"],"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 f2dd54ce..13bfc7da 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -404,17 +404,28 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv multiProblemSelectorButton.onclick = function(e) { e.preventDefault(); document.getElementById('id_name').disabled = true; - problemSelectorWindow = window.open( - lmsSelectorUrl + - '/lms-problem-selector?' + - "serverUrl=" + - encodeURIComponent(serverController.getSelectedServer().urlprefix) + - '&gradingType=all' + - '&origin=' + encodeURIComponent(window.location.origin) + - '&multiSelect=true', - "_blank", - 'toolbar=0,location=0,menubar=0' - ); + const selectedServer = serverController.getSelectedServer().urlprefix; + const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer) + ? '/auth/mumie/problem_selector.php?' + + 'org=' + mumieOrg + + '&serverurl=' + encodeURIComponent(selectedServer) + + '&problemlang=' + langController.getSelectedLanguage() + + '&origin=' + encodeURIComponent(window.location.origin) + + '&gradingtype=all' + + '&contextid=' + contextId + + '&multiselect=true' + : lmsSelectorUrl + + '/lms-problem-selector?' + + 'org=' + mumieOrg + + '&serverUrl=' + encodeURIComponent(selectedServer) + + '&problemLang=' + langController.getSelectedLanguage() + + '&origin=' + encodeURIComponent(window.location.origin) + + '&uiLang=' + systemLanguage + + '&gradingType=all' + + '&multiCourse=true' + + '&worksheet=true' + + '&multiSelect=true'; + problemSelectorWindow = window.open(multiUrl, "_blank", 'toolbar=0,location=0,menubar=0'); }; }, disable: function() { From 9e74412b40a1d05b7c4f0dac5bf7f4344e63494a Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 5 Jun 2026 16:46:34 +0200 Subject: [PATCH 053/101] Move multi-task creation logic from problemSelectorController to taskController to align with existing single-select architecture --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 307 +++++++++++++++++----------------- 3 files changed, 158 insertions(+), 153 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 9c25f17f..b0a53e70 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return void function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const items=tasks.map((t=>{const li=document.createElement("li");return li.textContent=t.name,li}));summary.innerHTML="";const label=document.createElement("div");label.textContent=tasks.length+" tasks selected:";const list=document.createElement("ul");list.style.margin="0.3em 0 0 1.2em",items.forEach((li=>list.appendChild(li))),summary.appendChild(label),summary.appendChild(list),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameItem=document.getElementById("fitem_id_name");nameItem&&nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((el=>{el.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none"),sendSuccess(),window.focus()}(importObj);const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0;const selectedServer=serverController.getSelectedServer().urlprefix,multiUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiUrl,"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,errorKey=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _config$configuration,_config$configuration2;if(!task.worksheet)continue;const config="string"==typeof task.worksheet?JSON.parse(task.worksheet):task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==config||null===(_config$configuration=config.configuration)||void 0===_config$configuration||null===(_config$configuration2=_config$configuration.correction)||void 0===_config$configuration2?void 0:_config$configuration2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(errorKey)return void require(["core/str"],(function(Str){Str.get_string(errorKey,"mod_mumie").then((function(msg){const field=document.getElementById("id_duration_selector"),fitem=field&&field.closest(".fitem");if(fitem){fitem.classList.add("has-danger");const feedback=fitem.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=msg,feedback.style.display="block");const section=fitem.closest(".collapse:not(.show)");if(section){section.classList.add("show");const btn=document.querySelector('[aria-controls="'+section.id+'"]');btn&&btn.setAttribute("aria-expanded","true")}}field&&(field.scrollIntoView({behavior:"smooth",block:"center"}),field.focus())}))}));const fitemClear=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(fitemClear){fitemClear.classList.remove("has-danger");const fb=fitemClear.querySelector(".form-control-feedback");fb&&(fb.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formdata=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[k,v]=_ref2;return encodeURIComponent(k)+"="+encodeURIComponent(v)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formdata}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){if(cancelClicked)return void(cancelClicked=!1);const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&tasksField.value&&(e.preventDefault(),problemSelectorController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0;const selectedServer=serverController.getSelectedServer().urlprefix,multiUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const items=tasks.map((t=>{const li=document.createElement("li");return li.textContent=t.name,li}));summary.innerHTML="";const label=document.createElement("div");label.textContent=tasks.length+" tasks selected:";const list=document.createElement("ul");list.style.margin="0.3em 0 0 1.2em",items.forEach((li=>list.appendChild(li))),summary.appendChild(label),summary.appendChild(list),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameItem=document.getElementById("fitem_id_name");nameItem&&nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((el=>{el.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,errorKey=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _config$configuration,_config$configuration2;if(!task.worksheet)continue;const config="string"==typeof task.worksheet?JSON.parse(task.worksheet):task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==config||null===(_config$configuration=config.configuration)||void 0===_config$configuration||null===(_config$configuration2=_config$configuration.correction)||void 0===_config$configuration2?void 0:_config$configuration2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(errorKey)return void require(["core/str"],(function(Str){Str.get_string(errorKey,"mod_mumie").then((function(msg){const field=document.getElementById("id_duration_selector"),fitem=field&&field.closest(".fitem");if(fitem){fitem.classList.add("has-danger");const feedback=fitem.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=msg,feedback.style.display="block");const section=fitem.closest(".collapse:not(.show)");if(section){section.classList.add("show");const btn=document.querySelector('[aria-controls="'+section.id+'"]');btn&&btn.setAttribute("aria-expanded","true")}}field&&(field.scrollIntoView({behavior:"smooth",block:"center"}),field.focus())}))}));const fitemClear=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(fitemClear){fitemClear.classList.remove("has-danger");const fb=fitemClear.querySelector(".form-control-feedback");fb&&(fb.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formdata=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[k,v]=_ref2;return encodeURIComponent(k)+"="+encodeURIComponent(v)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formdata}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){if(cancelClicked)return void(cancelClicked=!1);const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&tasksField.value&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 7eaad648..dd5021a2 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formdata = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formdata,\n };\n }\n\n /**\n * Handle multi-select postMessage: store tasks and show summary so teacher can adjust settings.\n * @param {Array} tasks array of task objects from the selector\n */\n function handleMultiSelect(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const items = tasks.map(t => {\n const li = document.createElement('li');\n li.textContent = t.name;\n return li;\n });\n summary.innerHTML = '';\n const label = document.createElement('div');\n label.textContent = tasks.length + ' tasks selected:';\n const list = document.createElement('ul');\n list.style.margin = '0.3em 0 0 1.2em';\n items.forEach(li => list.appendChild(li));\n summary.appendChild(label);\n summary.appendChild(list);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameItem = document.getElementById('fitem_id_name');\n if (nameItem) {\n nameItem.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(el => { el.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n sendSuccess();\n window.focus();\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet;\n const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const errorKey = validateWorksheetDeadlines(tasks);\n if (errorKey) {\n require(['core/str'], function(Str) {\n Str.get_string(errorKey, 'mod_mumie').then(function(msg) {\n const field = document.getElementById('id_duration_selector');\n const fitem = field && field.closest('.fitem');\n if (fitem) {\n fitem.classList.add('has-danger');\n const feedback = fitem.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = msg;\n feedback.style.display = 'block';\n }\n const section = fitem.closest('.collapse:not(.show)');\n if (section) {\n section.classList.add('show');\n const btn = document.querySelector('[aria-controls=\"' + section.id + '\"]');\n if (btn) {\n btn.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (field) {\n field.scrollIntoView({behavior: 'smooth', block: 'center'});\n field.focus();\n }\n });\n });\n return;\n }\n const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (fitemClear) {\n fitemClear.classList.remove('has-danger');\n const fb = fitemClear.querySelector('.form-control-feedback');\n if (fb) {\n fb.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\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\n if (Array.isArray(importObj)) {\n handleMultiSelect(importObj);\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n submitMultiTasks: submitMultiTasks,\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField && tasksField.value) {\n e.preventDefault();\n problemSelectorController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","tasks","tasksField","summary","items","map","t","li","createElement","textContent","innerHTML","label","length","list","margin","forEach","appendChild","nameField","nameItem","querySelectorAll","el","requiredLegend","querySelector","focus","handleMultiSelect","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiUrl","submitMultiTasks","courseId","_document$getElements","errorKey","hasDeadline","task","config","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","msg","field","fitem","closest","classList","add","feedback","section","btn","id","scrollIntoView","behavior","block","fitemClear","_document$getElementB2","remove","fb","settings","parseInt","URLSearchParams","search","get","submitBtn","form","sensitiveFields","formdata","from","FormData","filter","_ref","key","includes","_ref2","k","v","join","contextid","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelBtn"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const items = tasks.map(t => {\n const li = document.createElement('li');\n li.textContent = t.name;\n return li;\n });\n summary.innerHTML = '';\n const label = document.createElement('div');\n label.textContent = tasks.length + ' tasks selected:';\n const list = document.createElement('ul');\n list.style.margin = '0.3em 0 0 1.2em';\n items.forEach(li => list.appendChild(li));\n summary.appendChild(label);\n summary.appendChild(list);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameItem = document.getElementById('fitem_id_name');\n if (nameItem) {\n nameItem.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(el => { el.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formdata = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formdata,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet;\n const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const errorKey = validateWorksheetDeadlines(tasks);\n if (errorKey) {\n require(['core/str'], function(Str) {\n Str.get_string(errorKey, 'mod_mumie').then(function(msg) {\n const field = document.getElementById('id_duration_selector');\n const fitem = field && field.closest('.fitem');\n if (fitem) {\n fitem.classList.add('has-danger');\n const feedback = fitem.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = msg;\n feedback.style.display = 'block';\n }\n const section = fitem.closest('.collapse:not(.show)');\n if (section) {\n section.classList.add('show');\n const btn = document.querySelector('[aria-controls=\"' + section.id + '\"]');\n if (btn) {\n btn.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (field) {\n field.scrollIntoView({behavior: 'smooth', block: 'center'});\n field.focus();\n }\n });\n });\n return;\n }\n const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (fitemClear) {\n fitemClear.classList.remove('has-danger');\n const fb = fitemClear.querySelector('.form-control-feedback');\n if (fb) {\n fb.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField && tasksField.value) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","tasks","tasksField","summary","items","map","t","li","createElement","textContent","innerHTML","label","length","list","margin","forEach","appendChild","nameField","nameItem","querySelectorAll","el","requiredLegend","querySelector","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","errorKey","hasDeadline","task","config","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","msg","field","fitem","closest","classList","add","feedback","section","btn","id","scrollIntoView","behavior","block","fitemClear","_document$getElementB2","remove","fb","settings","parseInt","URLSearchParams","search","get","submitBtn","form","sensitiveFields","formdata","from","FormData","filter","_ref","key","_ref2","k","v","join","contextid","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelBtn"],"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 13bfc7da..21f669c7 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -138,153 +138,6 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }); } - /** - * Collect current form settings for multi-task creation. - * @returns {Object} form settings - */ - function collectFormSettings() { - const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0); - const submitBtn = document.getElementById('id_submitbutton'); - const form = submitBtn && submitBtn.closest('form'); - const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form']; - const formdata = form - ? Array.from(new FormData(form)) - .filter(([key]) => !sensitiveFields.includes(key)) - .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v)) - .join('&') - : ''; - return { - contextid: parseInt(contextId), - section: section, - formdata: formdata, - }; - } - - /** - * Handle multi-select postMessage: store tasks and show summary so teacher can adjust settings. - * @param {Array} tasks array of task objects from the selector - */ - function handleMultiSelect(tasks) { - const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; - const summary = document.getElementById('mumie_multi_tasks_summary'); - if (tasksField) { - tasksField.value = JSON.stringify(tasks); - } - if (summary) { - const items = tasks.map(t => { - const li = document.createElement('li'); - li.textContent = t.name; - return li; - }); - summary.innerHTML = ''; - const label = document.createElement('div'); - label.textContent = tasks.length + ' tasks selected:'; - const list = document.createElement('ul'); - list.style.margin = '0.3em 0 0 1.2em'; - items.forEach(li => list.appendChild(li)); - summary.appendChild(label); - summary.appendChild(list); - summary.style.display = 'block'; - } - const nameField = document.getElementById('id_name'); - nameField.disabled = true; - nameField.removeAttribute('required'); - const nameItem = document.getElementById('fitem_id_name'); - if (nameItem) { - nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]') - .forEach(el => { el.style.display = 'none'; }); - } - const requiredLegend = document.querySelector('.fdescription.required'); - if (requiredLegend) { - requiredLegend.style.display = 'none'; - } - sendSuccess(); - window.focus(); - } - - /** - * Validate worksheet deadline requirements against current duration_selector. - * Returns a lang string key if invalid, null if valid. - * @param {Array} tasks - * @returns {string|null} - */ - function validateWorksheetDeadlines(tasks) { - const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited'; - const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit'; - for (const task of tasks) { - if (!task.worksheet) { - continue; - } - const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet; - const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE'; - if (triggerAfterDeadline && !hasDeadline) { - return 'mumie_form_deadline_required_for_trigger_after_deadline'; - } - if (!triggerAfterDeadline && hasDeadline) { - return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'; - } - } - return null; - } - - /** - * Submit multi-tasks via AJAX using current form settings, then redirect to course. - */ - function submitMultiTasks() { - const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; - const courseId = document.getElementsByName('course')[0]?.value; - const tasks = JSON.parse(tasksField.value); - const errorKey = validateWorksheetDeadlines(tasks); - if (errorKey) { - require(['core/str'], function(Str) { - Str.get_string(errorKey, 'mod_mumie').then(function(msg) { - const field = document.getElementById('id_duration_selector'); - const fitem = field && field.closest('.fitem'); - if (fitem) { - fitem.classList.add('has-danger'); - const feedback = fitem.querySelector('.form-control-feedback'); - if (feedback) { - feedback.innerHTML = msg; - feedback.style.display = 'block'; - } - const section = fitem.closest('.collapse:not(.show)'); - if (section) { - section.classList.add('show'); - const btn = document.querySelector('[aria-controls="' + section.id + '"]'); - if (btn) { - btn.setAttribute('aria-expanded', 'true'); - } - } - } - if (field) { - field.scrollIntoView({behavior: 'smooth', block: 'center'}); - field.focus(); - } - }); - }); - return; - } - const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem'); - if (fitemClear) { - fitemClear.classList.remove('has-danger'); - const fb = fitemClear.querySelector('.form-control-feedback'); - if (fb) { - fb.style.display = 'none'; - } - } - const settings = collectFormSettings(); - settings.tasks = tasksField.value; - - require(['core/ajax', 'core/notification'], function(Ajax, Notification) { - Ajax.call([{ - methodname: 'mod_mumie_create_multiple_tasks', - args: settings, - }])[0].done(function() { - window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; - }).fail(Notification.exception); - }); - } - /** * Add an event listener that accepts messages from LMS-Browser and updates the selected problem. */ @@ -296,7 +149,9 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv const importObj = JSON.parse(event.data); if (Array.isArray(importObj)) { - handleMultiSelect(importObj); + taskController.setMultiSelection(importObj); + sendSuccess(); + window.focus(); return; } @@ -431,7 +286,6 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv disable: function() { problemSelectorButton.disabled = true; }, - submitMultiTasks: submitMultiTasks, }; })(); @@ -554,6 +408,151 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv durationController.setDurationElements(); } + /** + * Store selected tasks and update UI for multi-task creation. + * @param {Array} tasks array of task objects from the selector + */ + function setMultiSelection(tasks) { + const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; + const summary = document.getElementById('mumie_multi_tasks_summary'); + if (tasksField) { + tasksField.value = JSON.stringify(tasks); + } + if (summary) { + const items = tasks.map(t => { + const li = document.createElement('li'); + li.textContent = t.name; + return li; + }); + summary.innerHTML = ''; + const label = document.createElement('div'); + label.textContent = tasks.length + ' tasks selected:'; + const list = document.createElement('ul'); + list.style.margin = '0.3em 0 0 1.2em'; + items.forEach(li => list.appendChild(li)); + summary.appendChild(label); + summary.appendChild(list); + summary.style.display = 'block'; + } + const nameField = document.getElementById('id_name'); + nameField.disabled = true; + nameField.removeAttribute('required'); + const nameItem = document.getElementById('fitem_id_name'); + if (nameItem) { + nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]') + .forEach(el => { el.style.display = 'none'; }); + } + const requiredLegend = document.querySelector('.fdescription.required'); + if (requiredLegend) { + requiredLegend.style.display = 'none'; + } + } + + /** + * Collect current form settings for multi-task creation. + * @returns {Object} form settings + */ + function collectFormSettings() { + const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0); + const submitBtn = document.getElementById('id_submitbutton'); + const form = submitBtn && submitBtn.closest('form'); + const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form']; + const formdata = form + ? Array.from(new FormData(form)) + .filter(([key]) => !sensitiveFields.includes(key)) + .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v)) + .join('&') + : ''; + return { + contextid: parseInt(contextId), + section: section, + formdata: formdata, + }; + } + + /** + * Validate worksheet deadline requirements against current duration_selector. + * Returns a lang string key if invalid, null if valid. + * @param {Array} tasks + * @returns {string|null} + */ + function validateWorksheetDeadlines(tasks) { + const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited'; + const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit'; + for (const task of tasks) { + if (!task.worksheet) { + continue; + } + const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet; + const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE'; + if (triggerAfterDeadline && !hasDeadline) { + return 'mumie_form_deadline_required_for_trigger_after_deadline'; + } + if (!triggerAfterDeadline && hasDeadline) { + return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'; + } + } + return null; + } + + /** + * Submit multi-tasks via AJAX using current form settings, then redirect to course. + */ + function submitMultiTasks() { + const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; + const courseId = document.getElementsByName('course')[0]?.value; + const tasks = JSON.parse(tasksField.value); + const errorKey = validateWorksheetDeadlines(tasks); + if (errorKey) { + require(['core/str'], function(Str) { + Str.get_string(errorKey, 'mod_mumie').then(function(msg) { + const field = document.getElementById('id_duration_selector'); + const fitem = field && field.closest('.fitem'); + if (fitem) { + fitem.classList.add('has-danger'); + const feedback = fitem.querySelector('.form-control-feedback'); + if (feedback) { + feedback.innerHTML = msg; + feedback.style.display = 'block'; + } + const section = fitem.closest('.collapse:not(.show)'); + if (section) { + section.classList.add('show'); + const btn = document.querySelector('[aria-controls="' + section.id + '"]'); + if (btn) { + btn.setAttribute('aria-expanded', 'true'); + } + } + } + if (field) { + field.scrollIntoView({behavior: 'smooth', block: 'center'}); + field.focus(); + } + }); + }); + return; + } + const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem'); + if (fitemClear) { + fitemClear.classList.remove('has-danger'); + const fb = fitemClear.querySelector('.form-control-feedback'); + if (fb) { + fb.style.display = 'none'; + } + } + const settings = collectFormSettings(); + settings.tasks = tasksField.value; + + require(['core/ajax', 'core/notification'], function(Ajax, Notification) { + Ajax.call([{ + methodname: 'mod_mumie_create_multiple_tasks', + args: settings, + }])[0].done(function() { + window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; + }).fail(Notification.exception); + }); + } + return { init: function() { updateTaskDisplayElement(taskSelectionInput.value); @@ -577,7 +576,13 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }, getDelocalizedTaskLink: function() { return delocalizeLink(taskSelectionInput.value); - } + }, + setMultiSelection: setMultiSelection, + hasMultiTasks: function() { + const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; + return tasksField && !!tasksField.value; + }, + submitMultiTasks: submitMultiTasks, }; })(); @@ -747,7 +752,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; if (tasksField && tasksField.value) { e.preventDefault(); - problemSelectorController.submitMultiTasks(); + taskController.submitMultiTasks(); } }); } From 05d2114e739e35083f4bbdb740d28eb323c0c326 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 8 Jun 2026 11:42:46 +0200 Subject: [PATCH 054/101] cleanup, renaming parameter remove dead code, --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 103 +++++++++++++++++----------------- 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index b0a53e70..4ac2d55c 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0;const selectedServer=serverController.getSelectedServer().urlprefix,multiUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const items=tasks.map((t=>{const li=document.createElement("li");return li.textContent=t.name,li}));summary.innerHTML="";const label=document.createElement("div");label.textContent=tasks.length+" tasks selected:";const list=document.createElement("ul");list.style.margin="0.3em 0 0 1.2em",items.forEach((li=>list.appendChild(li))),summary.appendChild(label),summary.appendChild(list),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameItem=document.getElementById("fitem_id_name");nameItem&&nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((el=>{el.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,errorKey=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _config$configuration,_config$configuration2;if(!task.worksheet)continue;const config="string"==typeof task.worksheet?JSON.parse(task.worksheet):task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==config||null===(_config$configuration=config.configuration)||void 0===_config$configuration||null===(_config$configuration2=_config$configuration.correction)||void 0===_config$configuration2?void 0:_config$configuration2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(errorKey)return void require(["core/str"],(function(Str){Str.get_string(errorKey,"mod_mumie").then((function(msg){const field=document.getElementById("id_duration_selector"),fitem=field&&field.closest(".fitem");if(fitem){fitem.classList.add("has-danger");const feedback=fitem.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=msg,feedback.style.display="block");const section=fitem.closest(".collapse:not(.show)");if(section){section.classList.add("show");const btn=document.querySelector('[aria-controls="'+section.id+'"]');btn&&btn.setAttribute("aria-expanded","true")}}field&&(field.scrollIntoView({behavior:"smooth",block:"center"}),field.focus())}))}));const fitemClear=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(fitemClear){fitemClear.classList.remove("has-danger");const fb=fitemClear.querySelector(".form-control-feedback");fb&&(fb.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formdata=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[k,v]=_ref2;return encodeURIComponent(k)+"="+encodeURIComponent(v)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formdata}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){if(cancelClicked)return void(cancelClicked=!1);const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&tasksField.value&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0;const selectedServer=serverController.getSelectedServer().urlprefix,multiUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div");taskCountLabel.textContent=tasks.length+" tasks selected:";const taskList=document.createElement("ul");taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();function disableDropDownMenus(deadlineValidationError){require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:deadlineValidationError,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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 dd5021a2..808948dd 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const items = tasks.map(t => {\n const li = document.createElement('li');\n li.textContent = t.name;\n return li;\n });\n summary.innerHTML = '';\n const label = document.createElement('div');\n label.textContent = tasks.length + ' tasks selected:';\n const list = document.createElement('ul');\n list.style.margin = '0.3em 0 0 1.2em';\n items.forEach(li => list.appendChild(li));\n summary.appendChild(label);\n summary.appendChild(list);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameItem = document.getElementById('fitem_id_name');\n if (nameItem) {\n nameItem.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(el => { el.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formdata = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formdata,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet;\n const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const errorKey = validateWorksheetDeadlines(tasks);\n if (errorKey) {\n require(['core/str'], function(Str) {\n Str.get_string(errorKey, 'mod_mumie').then(function(msg) {\n const field = document.getElementById('id_duration_selector');\n const fitem = field && field.closest('.fitem');\n if (fitem) {\n fitem.classList.add('has-danger');\n const feedback = fitem.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = msg;\n feedback.style.display = 'block';\n }\n const section = fitem.closest('.collapse:not(.show)');\n if (section) {\n section.classList.add('show');\n const btn = document.querySelector('[aria-controls=\"' + section.id + '\"]');\n if (btn) {\n btn.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (field) {\n field.scrollIntoView({behavior: 'smooth', block: 'center'});\n field.focus();\n }\n });\n });\n return;\n }\n const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (fitemClear) {\n fitemClear.classList.remove('has-danger');\n const fb = fitemClear.querySelector('.form-control-feedback');\n if (fb) {\n fb.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField && tasksField.value) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","tasks","tasksField","summary","items","map","t","li","createElement","textContent","innerHTML","label","length","list","margin","forEach","appendChild","nameField","nameItem","querySelectorAll","el","requiredLegend","querySelector","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","errorKey","hasDeadline","task","config","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","msg","field","fitem","closest","classList","add","feedback","section","btn","id","scrollIntoView","behavior","block","fitemClear","_document$getElementB2","remove","fb","settings","parseInt","URLSearchParams","search","get","submitBtn","form","sensitiveFields","formdata","from","FormData","filter","_ref","key","_ref2","k","v","join","contextid","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelBtn"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n taskCountLabel.textContent = tasks.length + ' tasks selected:';\n const taskList = document.createElement('ul');\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\n }\n };\n })();\n\n /**\n * Disable all dropdown menus and show notification\n * @param {string} deadlineValidationError\n */\n function disableDropDownMenus(deadlineValidationError) {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': deadlineValidationError,\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","length","taskList","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","querySelector","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","errorMessage","durationSelectorField","workingPeriodContainer","closest","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","contextIdParam","prbSelectorUrl","isEdit","MumieServer","submitBtn","cancelClicked","cancelBtn"],"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 21f669c7..f7596b9f 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -419,28 +419,28 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv tasksField.value = JSON.stringify(tasks); } if (summary) { - const items = tasks.map(t => { - const li = document.createElement('li'); - li.textContent = t.name; - return li; + const taskListItems = tasks.map(task => { + const taskListItem = document.createElement('li'); + taskListItem.textContent = task.name; + return taskListItem; }); summary.innerHTML = ''; - const label = document.createElement('div'); - label.textContent = tasks.length + ' tasks selected:'; - const list = document.createElement('ul'); - list.style.margin = '0.3em 0 0 1.2em'; - items.forEach(li => list.appendChild(li)); - summary.appendChild(label); - summary.appendChild(list); + const taskCountLabel = document.createElement('div'); + taskCountLabel.textContent = tasks.length + ' tasks selected:'; + const taskList = document.createElement('ul'); + taskList.style.margin = '0.3em 0 0 1.2em'; + taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem)); + summary.appendChild(taskCountLabel); + summary.appendChild(taskList); summary.style.display = 'block'; } const nameField = document.getElementById('id_name'); nameField.disabled = true; nameField.removeAttribute('required'); - const nameItem = document.getElementById('fitem_id_name'); - if (nameItem) { - nameItem.querySelectorAll('.req, .text-danger, [title="Required field"]') - .forEach(el => { el.style.display = 'none'; }); + const nameFieldContainer = document.getElementById('fitem_id_name'); + if (nameFieldContainer) { + nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]') + .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; }); } const requiredLegend = document.querySelector('.fdescription.required'); if (requiredLegend) { @@ -454,19 +454,19 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv */ function collectFormSettings() { const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0); - const submitBtn = document.getElementById('id_submitbutton'); - const form = submitBtn && submitBtn.closest('form'); + const submitButton = document.getElementById('id_submitbutton'); + const form = submitButton && submitButton.closest('form'); const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form']; - const formdata = form + const formData = form ? Array.from(new FormData(form)) .filter(([key]) => !sensitiveFields.includes(key)) - .map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v)) + .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value)) .join('&') : ''; return { contextid: parseInt(contextId), section: section, - formdata: formdata, + formdata: formData, }; } @@ -483,8 +483,8 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv if (!task.worksheet) { continue; } - const config = typeof task.worksheet === 'string' ? JSON.parse(task.worksheet) : task.worksheet; - const triggerAfterDeadline = config?.configuration?.correction?.correctorType === 'AFTER_DEADLINE'; + const worksheetConfig = task.worksheet; + const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE'; if (triggerAfterDeadline && !hasDeadline) { return 'mumie_form_deadline_required_for_trigger_after_deadline'; } @@ -502,42 +502,44 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; const courseId = document.getElementsByName('course')[0]?.value; const tasks = JSON.parse(tasksField.value); - const errorKey = validateWorksheetDeadlines(tasks); - if (errorKey) { + const deadlineValidationError = validateWorksheetDeadlines(tasks); + if (deadlineValidationError) { require(['core/str'], function(Str) { - Str.get_string(errorKey, 'mod_mumie').then(function(msg) { - const field = document.getElementById('id_duration_selector'); - const fitem = field && field.closest('.fitem'); - if (fitem) { - fitem.classList.add('has-danger'); - const feedback = fitem.querySelector('.form-control-feedback'); + Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) { + const durationSelectorField = document.getElementById('id_duration_selector'); + const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem'); + if (workingPeriodContainer) { + workingPeriodContainer.classList.add('has-danger'); + const feedback = workingPeriodContainer.querySelector('.form-control-feedback'); if (feedback) { - feedback.innerHTML = msg; + feedback.innerHTML = errorMessage; feedback.style.display = 'block'; } - const section = fitem.closest('.collapse:not(.show)'); - if (section) { - section.classList.add('show'); - const btn = document.querySelector('[aria-controls="' + section.id + '"]'); - if (btn) { - btn.setAttribute('aria-expanded', 'true'); + const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)'); + if (collapsibleSection) { + collapsibleSection.classList.add('show'); + const sectionToggleButton = document.querySelector( + '[aria-controls="' + collapsibleSection.id + '"]' + ); + if (sectionToggleButton) { + sectionToggleButton.setAttribute('aria-expanded', 'true'); } } } - if (field) { - field.scrollIntoView({behavior: 'smooth', block: 'center'}); - field.focus(); + if (durationSelectorField) { + durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'}); + durationSelectorField.focus(); } }); }); return; } - const fitemClear = document.getElementById('id_duration_selector')?.closest('.fitem'); - if (fitemClear) { - fitemClear.classList.remove('has-danger'); - const fb = fitemClear.querySelector('.form-control-feedback'); - if (fb) { - fb.style.display = 'none'; + const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem'); + if (workingPeriodContainer) { + workingPeriodContainer.classList.remove('has-danger'); + const feedback = workingPeriodContainer.querySelector('.form-control-feedback'); + if (feedback) { + feedback.style.display = 'none'; } } const settings = collectFormSettings(); @@ -690,12 +692,12 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv /** * Disable all dropdown menus and show notification - * @param {string} errorKey + * @param {string} deadlineValidationError */ - function disableDropDownMenus(errorKey) { + function disableDropDownMenus(deadlineValidationError) { require(['core/str', "core/notification"], function(str, notification) { str.get_strings([{ - 'key': errorKey, + 'key': deadlineValidationError, component: 'mod_mumie' }]).done(function(s) { notification.addNotification({ @@ -749,8 +751,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv cancelClicked = false; return; } - const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; - if (tasksField && tasksField.value) { + if (taskController.hasMultiTasks()) { e.preventDefault(); taskController.submitMultiTasks(); } From 95858990ce1b851502e4e2d7c64162ab3ae3db61 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Mon, 8 Jun 2026 17:20:41 +0200 Subject: [PATCH 055/101] cleanup, renaming incorrect and inconsistent var, --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 4ac2d55c..3bc1bf86 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0;const selectedServer=serverController.getSelectedServer().urlprefix,multiUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div");taskCountLabel.textContent=tasks.length+" tasks selected:";const taskList=document.createElement("ul");taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();function disableDropDownMenus(deadlineValidationError){require(["core/str","core/notification"],(function(str,notification){str.get_strings([{key:deadlineValidationError,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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitBtn=document.getElementById("id_submitbutton"),form=submitBtn&&submitBtn.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0;const selectedServer=serverController.getSelectedServer().urlprefix,multiUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div");taskCountLabel.textContent=tasks.length+" tasks selected:";const taskList=document.createElement("ul");taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 808948dd..938fd9b2 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n taskCountLabel.textContent = tasks.length + ' tasks selected:';\n const taskList = document.createElement('ul');\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\n }\n };\n })();\n\n /**\n * Disable all dropdown menus and show notification\n * @param {string} deadlineValidationError\n */\n function disableDropDownMenus(deadlineValidationError) {\n require(['core/str', \"core/notification\"], function(str, notification) {\n str.get_strings([{\n 'key': deadlineValidationError,\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitBtn = document.getElementById('id_submitbutton');\n const form = submitBtn && submitBtn.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","length","taskList","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","querySelector","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","errorMessage","durationSelectorField","workingPeriodContainer","closest","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","contextIdParam","prbSelectorUrl","isEdit","MumieServer","submitBtn","cancelClicked","cancelBtn"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n taskCountLabel.textContent = tasks.length + ' tasks selected:';\n const taskList = document.createElement('ul');\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","length","taskList","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","querySelector","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","errorMessage","durationSelectorField","workingPeriodContainer","closest","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelBtn"],"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 f7596b9f..ad98223f 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -692,12 +692,12 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv /** * Disable all dropdown menus and show notification - * @param {string} deadlineValidationError + * @param {string} errorKey */ - function disableDropDownMenus(deadlineValidationError) { + function disableDropDownMenus(errorKey) { require(['core/str', "core/notification"], function(str, notification) { str.get_strings([{ - 'key': deadlineValidationError, + 'key': errorKey, component: 'mod_mumie' }]).done(function(s) { notification.addNotification({ @@ -736,8 +736,8 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }); } - const submitBtn = document.getElementById('id_submitbutton'); - const form = submitBtn && submitBtn.closest('form'); + const submitButton = document.getElementById('id_submitbutton'); + const form = submitButton && submitButton.closest('form'); if (form) { let cancelClicked = false; const cancelBtn = document.getElementById('id_cancel'); From a522bfdfbce557c2407d4cace7fe7dec7a7dd4c3 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 9 Jun 2026 11:33:36 +0200 Subject: [PATCH 056/101] last fixes, rename inconsistent vars, --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 34 ++++++++++++++++++++++++++++------ externallib.php | 4 ++-- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 3bc1bf86..10db841f 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),document.getElementById("id_name").disabled=!0;const selectedServer=serverController.getSelectedServer().urlprefix,multiUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div");taskCountLabel.textContent=tasks.length+" tasks selected:";const taskList=document.createElement("ul");taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelBtn=document.getElementById("id_cancel");cancelBtn&&cancelBtn.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div");taskCountLabel.textContent=tasks.length+" tasks selected:";const taskList=document.createElement("ul");taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 938fd9b2..8cb2d222 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 document.getElementById('id_name').disabled = true;\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n taskCountLabel.textContent = tasks.length + ' tasks selected:';\n const taskList = document.createElement('ul');\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelBtn = document.getElementById('id_cancel');\n if (cancelBtn) {\n cancelBtn.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","length","taskList","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","querySelector","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","errorMessage","durationSelectorField","workingPeriodContainer","closest","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelBtn"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n taskCountLabel.textContent = tasks.length + ' tasks selected:';\n const taskList = document.createElement('ul');\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasksField","summary","innerHTML","nameField","nameFieldContainer","querySelectorAll","forEach","requiredIndicator","requiredLegend","querySelector","updateName","updateGradeEditability","includes","split","tasks","taskListItems","map","task","taskListItem","createElement","textContent","taskCountLabel","length","taskList","margin","appendChild","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","errorMessage","durationSelectorField","workingPeriodContainer","closest","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 ad98223f..925b531f 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -258,9 +258,8 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv multiProblemSelectorButton.onclick = function(e) { e.preventDefault(); - document.getElementById('id_name').disabled = true; const selectedServer = serverController.getSelectedServer().urlprefix; - const multiUrl = shouldUseSSO(lmsSelectorUrl, selectedServer) + const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer) ? '/auth/mumie/problem_selector.php?' + 'org=' + mumieOrg + '&serverurl=' + encodeURIComponent(selectedServer) + @@ -280,7 +279,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv '&multiCourse=true' + '&worksheet=true' + '&multiSelect=true'; - problemSelectorWindow = window.open(multiUrl, "_blank", 'toolbar=0,location=0,menubar=0'); + problemSelectorWindow = window.open(multiSelectorUrl, "_blank", 'toolbar=0,location=0,menubar=0'); }; }, disable: function() { @@ -560,6 +559,29 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv updateTaskDisplayElement(taskSelectionInput.value); }, setSelection: function(link, language, name) { + const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; + if (tasksField) { + tasksField.value = ''; + } + const summary = document.getElementById('mumie_multi_tasks_summary'); + if (summary) { + summary.style.display = 'none'; + summary.innerHTML = ''; + } + const nameField = document.getElementById('id_name'); + if (nameField) { + nameField.disabled = false; + nameField.setAttribute('required', 'required'); + } + const nameFieldContainer = document.getElementById('fitem_id_name'); + if (nameFieldContainer) { + nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]') + .forEach(requiredIndicator => { requiredIndicator.style.display = ''; }); + } + const requiredLegend = document.querySelector('.fdescription.required'); + if (requiredLegend) { + requiredLegend.style.display = ''; + } updateTaskUri(link, language); updateName(name); }, @@ -740,9 +762,9 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv const form = submitButton && submitButton.closest('form'); if (form) { let cancelClicked = false; - const cancelBtn = document.getElementById('id_cancel'); - if (cancelBtn) { - cancelBtn.addEventListener('click', function() { + const cancelButton = document.getElementById('id_cancel'); + if (cancelButton) { + cancelButton.addEventListener('click', function() { cancelClicked = true; }); } diff --git a/externallib.php b/externallib.php index f01ebf76..fc7f5b35 100644 --- a/externallib.php +++ b/externallib.php @@ -189,7 +189,7 @@ public static function create_multiple_tasks($contextid, $section, $tasks, $form $privategradepool = (int)(isset($formfields['privategradepool']) ? $formfields['privategradepool'] : 0); $completionpass = (int)(isset($formfields['completionpass']) ? $formfields['completionpass'] : 0); $completionview = (int)($formfields['completionview'] ?? 0); - $isgraded = (int)($formfields['mumie_isgraded'] ?? 1); + $isgraded = (int)($formfields['isgraded'] ?? 1); $durationselector = $formfields['duration_selector'] ?? 'unlimited'; $duedate = 0; @@ -226,8 +226,8 @@ public static function create_multiple_tasks($contextid, $section, $tasks, $form } $moduleinfo->name = clean_param($taskdata['name'] ?? '', PARAM_TEXT); - $moduleinfo->taskurl = $tasklink; $moduleinfo->language = clean_param($taskdata['language'] ?? '', PARAM_TEXT); + $moduleinfo->taskurl = $tasklink . '?lang=' . $moduleinfo->language; $moduleinfo->mumie_coursefile = clean_param($taskdata['path_to_coursefile'] ?? '', PARAM_TEXT); $moduleinfo->mumie_course = clean_param($taskdata['course'] ?? '', PARAM_TEXT); $moduleinfo->server = $taskserver; From d026734ae88203aea48590b797542bf51916806a Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 9 Jun 2026 12:19:02 +0200 Subject: [PATCH 057/101] Fix multi-task creation: read isGraded per task, correct isgraded field name, append lang suffix to taskurl --- externallib.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/externallib.php b/externallib.php index fc7f5b35..f6688eac 100644 --- a/externallib.php +++ b/externallib.php @@ -189,7 +189,6 @@ public static function create_multiple_tasks($contextid, $section, $tasks, $form $privategradepool = (int)(isset($formfields['privategradepool']) ? $formfields['privategradepool'] : 0); $completionpass = (int)(isset($formfields['completionpass']) ? $formfields['completionpass'] : 0); $completionview = (int)($formfields['completionview'] ?? 0); - $isgraded = (int)($formfields['isgraded'] ?? 1); $durationselector = $formfields['duration_selector'] ?? 'unlimited'; $duedate = 0; @@ -239,7 +238,7 @@ public static function create_multiple_tasks($contextid, $section, $tasks, $form $moduleinfo->duration_selector = $durationselector; $moduleinfo->duedate = $duedate; $moduleinfo->timelimit = $timelimit; - $moduleinfo->isgraded = $isgraded; + $moduleinfo->isgraded = (int)($taskdata['isGraded'] ?? 1); $moduleinfo->grade = $points; $moduleinfo->gradepass = $gradepass; From 5125845a78fda6bd630cde19fad25cfca4eef74a Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 9 Jun 2026 14:21:54 +0200 Subject: [PATCH 058/101] Add localization for task count label, bump version to v1.9.2 --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 7 ++++++- lang/de/mumie.php | 3 ++- lang/en/mumie.php | 3 ++- version.php | 4 ++-- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 10db841f..ec805602 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div");taskCountLabel.textContent=tasks.length+" tasks selected:";const taskList=document.createElement("ul");taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none")}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 8cb2d222..c0fb88f9 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n taskCountLabel.textContent = tasks.length + ' tasks selected:';\n const taskList = document.createElement('ul');\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasksField","summary","innerHTML","nameField","nameFieldContainer","querySelectorAll","forEach","requiredIndicator","requiredLegend","querySelector","updateName","updateGradeEditability","includes","split","tasks","taskListItems","map","task","taskListItem","createElement","textContent","taskCountLabel","length","taskList","margin","appendChild","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","Str","get_string","then","errorMessage","durationSelectorField","workingPeriodContainer","closest","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasksField","summary","innerHTML","nameField","nameFieldContainer","querySelectorAll","forEach","requiredIndicator","requiredLegend","querySelector","updateName","updateGradeEditability","includes","split","tasks","taskListItems","map","task","taskListItem","createElement","textContent","taskCountLabel","taskList","Str","get_string","length","then","label","margin","appendChild","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","errorMessage","durationSelectorField","workingPeriodContainer","closest","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","checkbox","checked","push","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"mappings":"AAAAA,4BAAO,CAAC,SAAU,iBAAkB,qBAAsB,iCAAkC,cACxF,iBACUC,gBAAkBC,SAASC,eAAe,wBAC1CC,cAAgBF,SAASG,kBAAkB,wBAAwB,OACrEC,eACAC,eACAC,gBAGEC,mBAAsB,iBAElBC,iBAAmBR,SAASC,eAAe,wBAC3CQ,WAAaT,SAASC,eAAe,8BAKlCS,mBACuB,MAArBD,WAAWE,eAMbC,yBACYF,cAEbF,iBAAiBK,aAAa,WAAY,YAC1CL,iBAAiBG,MAAQ,aAEzBH,iBAAiBM,gBAAgB,YAKN,cAA3BN,iBAAiBG,OACjBX,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,sBAAsBc,MAAMC,QALpC,OAMhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QANzC,OAOhBhB,SAASC,eAAe,oBAAoBc,MAAMC,QAPlC,OAQhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QARvC,QASkB,YAA3BR,iBAAiBG,OACxBX,SAASC,eAAe,oBAAoBc,MAAMC,QAAU,GAC5DhB,SAASC,eAAe,yBAAyBc,MAAMC,QAAU,GAEjEhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAbzC,OAchBhB,SAASC,eAAe,sBAAsBc,MAAMC,QAdpC,OAehBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAfzC,QAgBkB,cAA3BR,iBAAiBG,QACxBX,SAASC,eAAe,sBAAsBc,MAAMC,QAAU,GAC9DhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,oBAAoBc,MAAMC,QApBlC,OAqBhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QArBvC,OAsBhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAtBzC,cA0BjB,CACHC,KAAM,WACFT,iBAAiBU,SAAW,WACxBN,0BAEJO,OAAOC,iBAAiB,QAAQ,KAC5BR,4BAEJA,0BAEJS,oBAAqBT,uBACrBF,WAAYA,WACZY,mBAAoB,SAASC,UACzBd,WAAWE,MAAQY,SAAW,IAAM,KAExCC,mBAAoB,kBACTf,WAAWE,QAlEF,GAuEtBc,iBAAoB,eAClBC,sBACEC,eAAiB3B,SAASC,eAAe,mBAExC,CACHgB,KAAM,SAASW,WACXF,gBAAkBE,WAEtBC,kBAAmB,iBACTC,mBAAqBH,eAAeI,QAAQJ,eAAeK,eAAeC,YACzEP,gBAAgBQ,MAAKC,QAAUA,OAAOC,OAASN,sBAE1DO,QAAS,WACLV,eAAeW,UAAW,WA4rBZC,WACfA,KAAKC,YACRD,KAAKE,YAAYF,KAAKC,YA7rBlBE,CAAiBf,kBAdH,GAmBpBgB,0BAA6B,iBACzBC,sBAAwB5C,SAASC,eAAe,uBAChD4C,2BAA6B7C,SAASC,eAAe,qCACvD6C,4BACEC,SAAW/C,SAASG,kBAAkB,aAAa,GAAGQ,eAQnDqC,aAAaC,UACbH,uBAGLA,sBAAsBI,YAAYC,KAAKC,UAAUH,UAAW7C,yBAOvDiD,kBAAYC,+DAAU,GAC3BN,aAAa,CACTO,SAAS,EACTD,QAASA,mBAkBRE,qBACLrC,OAAOC,iBAAiB,WAAYqC,oCAC5BA,MAAMC,SAAWtD,4BAGfuD,UAAYR,KAAKS,MAAMH,MAAMI,SAE/BC,MAAMC,QAAQJ,kBACdK,eAAeC,kBAAkBN,WACjCN,mBACAlC,OAAO+C,cAIL3C,UAAkC,IAAvBoC,UAAUpC,SACrB4C,uCAAYR,UAAUQ,+DAAa,SAErCC,iBAAiBC,UAAUV,UAAUW,oBACrCC,eAAeC,YAAYb,UAAUc,UACrCT,eAAeU,aAAaf,UAAUgB,KAAMhB,UAAUc,SAAUd,UAAUvB,MAC1E4B,eAAeY,YAAYrD,UAC3BsD,oBAAoBC,aAAaX,WACjCd,cACAlC,OAAO+C,QAYfa,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN,+BACPC,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBhC,QAAS+B,EAAE,GACXE,KAAM,YAEXC,KAAKP,aAAaQ,cAnBnB,MAAOC,mBAlCb1C,aAAa,CACTO,SAAS,EACTD,+DAHuB,KAoCnBqC,CAAYD,MAAMpC,aAEvB,YAmEEsC,aAAaC,mBAAoBC,0BAC/B,IAAIC,IAAIF,oBAAoBnC,SAAW,IAAIqC,IAAID,mBAAmBpC,aAGtE,CACHzC,KAAM,WACF2B,sBAAsBoD,QAAU,WAC5BlD,sBAAwB3B,OAAO8E,sBAjDjCC,YAAclC,eAAemC,iBAC7BC,UAAYpC,eAAeqC,yBAC3BC,eAAiB7E,iBAAiBI,oBAAoB0E,iBAC7CX,aAAaxF,eAAgBkG,gBAEjC,wCAEHvD,SACA,cACAyD,mBAAmBF,gBACnB,gBACA/B,eAAekC,sBACf,WAAaD,mBAAmBrF,OAAOuF,SAAShD,QAChD,gBAAkBwC,YAClB,cAAgB5F,WACf8F,UAAY,cAAgBA,UAAY,IAE1ChG,eAAAA,6BAGH2C,SACA,cACAyD,mBAAmBF,gBACnB,gBACA/B,eAAekC,sBACf,WAAaD,mBAAmBrF,OAAOuF,SAAShD,QAChD,WAAarD,eACb,gBAAkB6F,YAVf9F,oCAaFgG,UAAY,cAAgBA,UAAY,IAmBDO,GAAY,WAGpDxF,OAAOyF,QAAU,WACbvD,eAGJlC,OAAOC,iBAAiB,gBAAgB,WACpCiC,iBACD,GAEHG,qBAEAX,2BAA2BmD,QAAU,SAASa,GAC1CA,EAAEC,uBACIR,eAAiB7E,iBAAiBI,oBAAoB0E,UACtDQ,iBAAmBnB,aAAaxF,eAAgBkG,gBAChD,wCACWvD,SACT,cAAgByD,mBAAmBF,gBACnC,gBAAkB/B,eAAekC,sBACjC,WAAaD,mBAAmBrF,OAAOuF,SAAShD,QAJlD,8BAMkBpD,UAChB,oBACFF,eAAAA,6BAEW2C,SACT,cAAgByD,mBAAmBF,gBACnC,gBAAkB/B,eAAekC,sBACjC,WAAaD,mBAAmBrF,OAAOuF,SAAShD,QAChD,WAAarD,eANfD,oEAWN0C,sBAAwB3B,OAAO8E,KAAKc,iBAAkB,SAAU,oCAGxE1E,QAAS,WACLO,sBAAsBN,UAAW,IA1LV,GA+L7B8B,iBAAoB,iBAChB4C,eAAiBhH,SAASC,eAAe,mBACzCgH,eAAiBjH,SAASG,kBAAkB,oBAAoB,YAgB7D+G,mDACCC,eAAiB/C,iBAAiBgD,oBAClCC,iBAAmB9C,eAAekC,sBACnCU,gBAAmBE,mBAGxBL,eAAerG,oCAAQwG,eAAe/E,KACjCF,MAAKoF,aAAeA,YAAY7C,WAAa4C,2DAD3BE,sBAC8C5G,aAGlE,CACHM,KAAM,WACFiG,oBAEJE,kBAAmB,kBACC3F,iBAAiBI,oBAAoB2F,QACtCtF,MAAKuF,QAAUA,OAAOC,aAAeT,eAAetG,SAEvE0D,UAAW,SAASsD,gBA1BMD,WAAAA,WA2BDC,WA1BzBV,eAAetG,MAAQ+G,WACvBR,qBAZkB,GA0CpB3C,eAAkB,iBACdqD,aAAe5H,SAASC,eAAe,qBACtC,CACHwG,oBAAqB,kBACVmB,aAAajH,OAExB6D,YAAa,SAASqD,MAClBD,aAAajH,MAAQkH,OAPT,GAYlB7D,eAAkB,iBACd8D,mBAAqB9H,SAASG,kBAAkB,WAAW,GAC3D4H,SAAW/H,SAASC,eAAe,WACnC+H,mBAAqBhI,SAASC,eAAe,oCAc1CgI,yBAAyBC,eAC9BF,mBAAmBrH,MAAQuH,uBAQtBC,cAAcxD,KAAMF,gBACnByD,uBAWYvD,KAAMF,iBACjBE,KAnCuB,SAmCYF,SAZpB2D,CAAazD,KAAMF,UACzCqD,mBAAmBnH,MAAQuH,cAC3BD,yBAAyBC,qBA4LtB,CACHjH,KAAM,WACFgH,yBAAyBH,mBAAmBnH,QAEhD+D,aAAc,SAASC,KAAMF,SAAUrC,YAC7BiG,WAAarI,SAASG,kBAAkB,qBAAqB,GAC/DkI,aACAA,WAAW1H,MAAQ,UAEjB2H,QAAUtI,SAASC,eAAe,6BACpCqI,UACAA,QAAQvH,MAAMC,QAAU,OACxBsH,QAAQC,UAAY,UAElBC,UAAYxI,SAASC,eAAe,WACtCuI,YACAA,UAAUlG,UAAW,EACrBkG,UAAU3H,aAAa,WAAY,mBAEjC4H,mBAAqBzI,SAASC,eAAe,iBAC/CwI,oBACAA,mBAAmBC,iBAAiB,gDAC/BC,SAAQC,oBAAuBA,kBAAkB7H,MAAMC,QAAU,YAEpE6H,eAAiB7I,SAAS8I,cAAc,0BAC1CD,iBACAA,eAAe9H,MAAMC,QAAU,IAEnCmH,cAAcxD,KAAMF,mBA3ORrC,MAChB2F,SAASpH,MAAQyB,KA2Ob2G,CAAW3G,OAEfwC,YAAa,SAASrD,UAClBhB,mBAAmBe,mBAAmBC,2BA/LpCe,SAAW/B,mBAAmBG,aACpCV,SAASC,eAAe,aAAaqC,SAAWA,SAChDtC,SAASC,eAAe,gBAAgBqC,SAAWA,SACnDtC,SAASC,eAAe,eAAeqC,SAAWA,SAClD/B,mBAAmBc,sBA4Lf2H,IAEJ7C,eAAgB,iBACN5E,SAAWhB,mBAAmBiB,2BACnB,MAAbD,SACO,SACa,MAAbA,SACA,WAEJ,OAEX8E,uBAAwB,kBAtNJ1B,KAuNMmD,mBAAmBnH,OAtNpCsI,SA5CqB,UA6CnBtE,KAAKuE,MA7Cc,UA6CmB,GAE1CvE,SAJaA,MAyNpBV,2BAnMuBkF,aACjBd,WAAarI,SAASG,kBAAkB,qBAAqB,GAC7DmI,QAAUtI,SAASC,eAAe,gCACpCoI,aACAA,WAAW1H,MAAQwC,KAAKC,UAAU+F,QAElCb,QAAS,OACHc,cAAgBD,MAAME,KAAIC,aACtBC,aAAevJ,SAASwJ,cAAc,aAC5CD,aAAaE,YAAcH,KAAKlH,KACzBmH,gBAEXjB,QAAQC,UAAY,SACdmB,eAAiB1J,SAASwJ,cAAc,OACxCG,SAAW3J,SAASwJ,cAAc,MACxCzE,QAAQ,CAAC,aAAa,SAAS6E,KAC3BA,IAAIC,WAAW,6BAA8B,YAAaV,MAAMW,QAC3DC,MAAK,SAASC,OACXN,eAAeD,YAAcO,YAGzCL,SAAS5I,MAAMkJ,OAAS,kBACxBb,cAAcT,SAAQY,cAAgBI,SAASO,YAAYX,gBAC3DjB,QAAQ4B,YAAYR,gBACpBpB,QAAQ4B,YAAYP,UACpBrB,QAAQvH,MAAMC,QAAU,cAEtBwH,UAAYxI,SAASC,eAAe,WAC1CuI,UAAUlG,UAAW,EACrBkG,UAAU1H,gBAAgB,kBACpB2H,mBAAqBzI,SAASC,eAAe,iBAC/CwI,oBACAA,mBAAmBC,iBAAiB,gDAC/BC,SAAQC,oBAAuBA,kBAAkB7H,MAAMC,QAAU,gBAEpE6H,eAAiB7I,SAAS8I,cAAc,0BAC1CD,iBACAA,eAAe9H,MAAMC,QAAU,SA+JnCmJ,cAAe,iBACL9B,WAAarI,SAASG,kBAAkB,qBAAqB,UAC5DkI,cAAgBA,WAAW1H,OAEtCyJ,mFA5GM/B,WAAarI,SAASG,kBAAkB,qBAAqB,GAC7DkK,uCAAWrK,SAASG,kBAAkB,UAAU,2CAArCmK,sBAAyC3J,MAEpD4J,iCA1B0BpB,uCAC1B3I,gDAAmBR,SAASC,eAAe,sFAAyBU,QAAS,YAC7E6J,YAAmC,YAArBhK,kBAAuD,cAArBA,qBACjD,MAAM8I,QAAQH,MAAO,sDACjBG,KAAKnF,yBAGJsG,gBAAkBnB,KAAKnF,UACvBuG,qBAAqF,oBAA9DD,MAAAA,+CAAAA,gBAAiBE,qGAAeC,2EAAYC,kBACrEH,uBAAyBF,kBAClB,8DAENE,sBAAwBF,kBAClB,qFAGR,KAUyBM,CADlB3H,KAAKS,MAAMyE,WAAW1H,WAEhC4J,oCACAxF,QAAQ,CAAC,aAAa,SAAS6E,KAC3BA,IAAIC,WAAWU,wBAAyB,aAAaR,MAAK,SAASgB,oBACzDC,sBAAwBhL,SAASC,eAAe,wBAChDgL,uBAAyBD,uBAAyBA,sBAAsBE,QAAQ,aAClFD,uBAAwB,CACxBA,uBAAuBE,UAAUC,IAAI,oBAC/BC,SAAWJ,uBAAuBnC,cAAc,0BAClDuC,WACAA,SAAS9C,UAAYwC,aACrBM,SAAStK,MAAMC,QAAU,eAEvBsK,mBAAqBL,uBAAuBC,QAAQ,2BACtDI,mBAAoB,CACpBA,mBAAmBH,UAAUC,IAAI,cAC3BG,oBAAsBvL,SAAS8I,cACjC,mBAAqBwC,mBAAmBE,GAAK,MAE7CD,qBACAA,oBAAoB1K,aAAa,gBAAiB,SAI1DmK,wBACAA,sBAAsBS,eAAe,CAACC,SAAU,SAAUC,MAAO,WACjEX,sBAAsB9G,qBAMhC+G,sDAAyBjL,SAASC,eAAe,iEAAxB2L,uBAAiDV,QAAQ,aACpFD,uBAAwB,CACxBA,uBAAuBE,UAAUU,OAAO,oBAClCR,SAAWJ,uBAAuBnC,cAAc,0BAClDuC,WACAA,SAAStK,MAAMC,QAAU,cAG3B8K,0BAzFAC,QAAUC,SAAS,IAAIC,gBAAgB9K,OAAOuF,SAASwF,QAAQC,IAAI,YAAc,GACjFC,aAAepM,SAASC,eAAe,mBACvCoM,KAAOD,cAAgBA,aAAalB,QAAQ,QAC5CoB,gBAAkB,CAAC,UAAW,2BAC9BC,SAAWF,KACXvI,MAAM0I,KAAK,IAAIC,SAASJ,OACrBK,QAAOC,WAAEC,iBAAUN,gBAAgBrD,SAAS2D,QAC5CvD,KAAIwD,YAAED,IAAKjM,oBAAW6F,mBAAmBoG,KAAO,IAAMpG,mBAAmB7F,UACzEmM,KAAK,KACR,SACC,CACHC,UAAWf,SAAS1L,WACpByL,QAASA,QACTiB,SAAUT,UA4EGU,GACjBnB,SAAS3C,MAAQd,WAAW1H,MAE5BoE,QAAQ,CAAC,YAAa,sBAAsB,SAASmI,KAAMC,cACvDD,KAAKE,KAAK,CAAC,CACPC,WAAY,kCACZC,KAAMxB,YACN,GAAG1G,MAAK,WACRjE,OAAOuF,SAAS6G,KAAOC,EAAEC,IAAIC,QAAU,uBAAyBrD,YACjE7E,KAAK2H,aAAa1H,gBArNT,GAkRlBkI,wBAA2B,iBACvBC,wBAA0B5N,SAASG,kBAAkB,6BACrD0N,uBAAyB7N,SAASG,kBAAkB,kCAAkC,OACxF2N,iBAAmB,SACjBC,oBAAsB/N,SAASG,kBAAkB,yBACjD6N,cAAgBhO,SAASG,kBAAkB,wBAAwB,OACrE8N,gBAAkB,SAChBC,cAAgBlO,SAASG,kBAAkB,kCAwE1C,CACHc,KAAM,WAvDN8M,oBAAoBpF,SAAQ,SAASwF,UACjCA,SAASjN,SAAW,WACXiN,SAASC,QAGVH,gBAAgBI,KAAKF,SAASxN,OAF9BsN,gBAAkBA,gBAAgBvB,QAAOnK,MAAQA,OAAS4L,SAASxN,QAIvEqN,cAAcrN,MAAQwC,KAAKC,UAAU6K,qBAS7CL,wBAAwBjF,SAAQ,SAASwF,UACrCA,SAASjN,SAAW,WACXiN,SAASC,QAGVN,iBAAiBO,KAAKF,SAASxN,OAF/BmN,iBAAmBA,iBAAiBpB,QAAOnK,MAAQA,OAAS4L,SAASxN,QAIzEkN,uBAAuBlN,MAAQwC,KAAKC,UAAU0K,sBAStDI,cAAcvF,SAAQ,SAAS2F,iBAC3BA,gBAAgBpN,SAAW,WAClBoN,gBAAgBF,QAQjBL,oBAAoBpF,SAAQ,SAAS4F,kBApD5BC,MAAOC,QAqDRF,aAAaG,aAAa,aAAeJ,gBAAgB3N,QACzD4N,aAAaH,SAAU,EAtDtBI,MAuDeP,gBAvDRQ,QAuDyBF,aAAa5N,MAtD7D6N,MAAMvF,SAASwF,UAChBD,MAAMH,KAAKI,aA2CHV,oBAAoBpF,SAAQ,SAAS4F,cAC7BA,aAAaG,aAAa,aAAeJ,gBAAgB3N,QACzD4N,aAAaH,SAAU,EACvBH,gBAAkBA,gBAAgBvB,QAAOnK,MAAQgM,aAAa5N,QAAU4B,WAWpFyL,cAAcrN,MAAQwC,KAAKC,UAAU6K,uBA1EpB,GAwF3BpJ,oBAAuB,iBACnB8J,iBAAmB3O,SAASC,eAAe,4BAC1C,CACH6E,aAAc,SAASX,WACfA,UACAwK,iBAAiB9N,aAAa,QAASsC,KAAKC,UAAUe,YAEtDwK,iBAAiB7N,gBAAgB,WAPpB,YAiBpB8N,qBAAqBC,UAC1B9J,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN2J,SACP1J,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBhC,QAAS+B,EAAE,GAAK,MAAQnF,cAAcwO,aAAa,SAAW,OAC9DnJ,KAAM,eAEXC,KAAKP,aAAaQ,cAEzBhE,iBAAiBY,UACjBM,0BAA0BN,gBAGvB,CACHpB,KAAM,SAAS6N,eAAgBC,eAAgBlH,MAC3CzH,eAAiB2O,eACjB1O,eAAiBwH,KACjBvH,UAAYwO,qBACNE,OAAShP,SAASC,eAAe,WAAWyO,aAAa,SACzDhN,gBAAkByB,KAAKS,MAAM5D,SAASG,kBAAkB,0BAA0B,GAAGQ,OACvFqO,QA0D+E,KAAhFhP,SAASG,kBAAkB,wBAAwB,GAAGuO,aAAa,SAzDlEE,qBAAqB,6BACblN,gBAAgBoI,QAGxBrI,iBAAiBR,KAAKS,iBACtB0C,iBAAiBnD,OACjB+C,eAAe/C,OACf0M,wBAAwB1M,OACxB0B,0BAA0B1B,OAC1BV,mBAAmBU,QAPnB2N,qBAAqB,6BASzBjB,wBAAwB1M,OACpBlB,iBACAgF,QAAQ,CAAC,mCAAmC,SAASkK,aACjDA,YAAYhO,KAAKlB,gBAAiBO,oBAIpC8L,aAAepM,SAASC,eAAe,mBACvCoM,KAAOD,cAAgBA,aAAalB,QAAQ,WAC9CmB,KAAM,KACF6C,eAAgB,QACdC,aAAenP,SAASC,eAAe,aACzCkP,cACAA,aAAa/N,iBAAiB,SAAS,WACnC8N,eAAgB,KAGxB7C,KAAKjL,iBAAiB,UAAU,SAASyF,GACjCqI,cACAA,eAAgB,EAGhBlL,eAAemG,kBACftD,EAAEC,iBACF9C,eAAeoG"} \ No newline at end of file diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 925b531f..e5055a1a 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -425,8 +425,13 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }); summary.innerHTML = ''; const taskCountLabel = document.createElement('div'); - taskCountLabel.textContent = tasks.length + ' tasks selected:'; const taskList = document.createElement('ul'); + require(['core/str'], function(Str) { + Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length) + .then(function(label) { + taskCountLabel.textContent = label; + }); + }); taskList.style.margin = '0.3em 0 0 1.2em'; taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem)); summary.appendChild(taskCountLabel); diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 2e38082a..db3711a8 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -126,7 +126,8 @@ $string['mumie_grade_overridden'] = 'Bewertung erfolgreich gespeichert!'; $string['mumie_grade_percentage'] = 'Bewerung in %'; $string['mumie_grading_settings'] = "Individuelle Bewertungseinstellungen"; -$string['mumie_multi_problem_selector'] = 'Alternativ können Sie mit der Mehrfach-Aufgabenauswahl auch mehrere MUMIE-Aufgaben auf einmal auswählen. Alle Aufgaben werden mit den eingestellten Einstellungen angelegt (Punkte, Frist, Startcontainer etc.). Jede Aufgabe behält ihren eigenen Namen — anders als bei der Einzelauswahl kann kein eigener Name vergeben werden.

Weitere Informationen finden Sie in unserem Wiki'; +$string['mumie_multi_tasks_selected'] = '{$a} Tasks ausgewählt:'; +$string['mumie_multi_problem_selector'] ='Alternativ können Sie mit der Mehrfach-Aufgabenauswahl auch mehrere MUMIE-Aufgaben auf einmal auswählen. Alle Aufgaben werden mit den eingestellten Einstellungen angelegt (Punkte, Frist, Startcontainer etc.). Jede Aufgabe behält ihren eigenen Namen — anders als bei der Einzelauswahl kann kein eigener Name vergeben werden.

Weitere Informationen finden Sie in unserem Wiki'; $string['mumie_no_other_task_found'] = 'Keine andere MUMIE Tasks in Kurs gefunden'; $string['mumie_no_submissions'] = 'Keine Antworten abgegeben'; $string['mumie_open_task'] = 'MUMIE-Task öffnen'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 5628402a..647ad68f 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -121,7 +121,8 @@ $string['mumie_grade_overridden'] = 'Updated grade successfully!'; $string['mumie_grade_percentage'] = 'Grade in %'; $string['mumie_grading_settings'] = "Individual grading settings"; -$string['mumie_multi_problem_selector'] = 'Alternatively, you can also create multiple MUMIE Tasks at once using the Multi Problem Selector. All tasks will be created with the settings configured (points, deadline, container type, etc.). Each task keeps its own name — unlike single task creation, no custom name can be assigned.

For more information, have a look at our wiki'; +$string['mumie_multi_tasks_selected'] = '{$a} tasks selected:'; +$string['mumie_multi_problem_selector'] ='Alternatively, you can also create multiple MUMIE Tasks at once using the Multi Problem Selector. All tasks will be created with the settings configured (points, deadline, container type, etc.). Each task keeps its own name — unlike single task creation, no custom name can be assigned.

For more information, have a look at our wiki'; $string['mumie_no_other_task_found'] = 'No other MUMIE Tasks found in course'; $string['mumie_no_submissions'] = 'No answers submitted'; $string['mumie_open_task'] = 'Open MUMIE Task'; diff --git a/version.php b/version.php index d7e9063f..88262dae 100644 --- a/version.php +++ b/version.php @@ -25,10 +25,10 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2025070300; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2026060900; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2022112800; // 4.1 LTS -$plugin->release = "v1.9.1"; +$plugin->release = "v1.9.2"; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = [ 'auth_mumie' => 2025051500, From 6295c6df7cc1e51520d8b59c2347507e17731c25 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 9 Jun 2026 17:04:03 +0200 Subject: [PATCH 059/101] fix git pipeline issues --- lang/de/mumie.php | 8 ++++---- lang/en/mumie.php | 8 ++++---- mod_form.php | 2 +- styles.css | 7 +++++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lang/de/mumie.php b/lang/de/mumie.php index e32acae4..58dbc821 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -92,8 +92,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_coursefile'] = 'Path to MUMIE course meta file'; -$string['mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, die bereits den Bearbeitungszeitraum Typ \'Abgabefrist\' haben.'; $string['mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'] = "Das ausgewählte Worksheet darf keinen begrenzten Bearbeitungszeitraum haben.

Wählen Sie ein Worksheet mit entsprechender Konfiguration aus, wenn Sie eine Frist setzen möchten."; +$string['mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, die bereits den Bearbeitungszeitraum Typ \'Abgabefrist\' haben.'; $string['mumie_form_deadline_required_for_trigger_after_deadline'] = "Das ausgewählte Worksheet setzt einen festgelegten Bearbeitungszeitraum voraus"; $string['mumie_form_due_date_must_be_future'] = 'Das Datum der Abgabefrist kann nicht in der Vergangenheit liegen!'; $string['mumie_form_filter'] = 'MUMIE-Tasks filtern'; @@ -117,10 +117,10 @@ $string['mumie_form_task_properties_selection_info'] = 'Wählen Sie die Eigenschaften dieser MUMIE-Task aus, die in anderen MUMIE-Tasks übernommen werden sollen.'; $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'; -$string['mumie_form_tasks_selection_info'] = 'Bestimmen Sie die MUMIE-Tasks, für die die ausgewählten Eigenschaften ebenfalls übernommen werden sollen.'; $string['mumie_form_due_date_multi_edit_hint'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, welche vorher bereits mit dem Bearbeitungszeitraum Typ \'Abgabefrist\' erstellt wurden.'; -$string['mumie_form_working_period_not_duedate_warning'] = 'Bearbeitungszeitraum: keine Abgabefrist'; +$string['mumie_form_tasks_selection_info'] = 'Bestimmen Sie die MUMIE-Tasks, für die die ausgewählten Eigenschaften ebenfalls übernommen werden sollen.'; $string['mumie_form_topic'] = 'Thema: {$a}'; +$string['mumie_form_working_period_not_duedate_warning'] = 'Bearbeitungszeitraum: keine Abgabefrist'; $string['mumie_form_updated_selection'] = 'Aufgabe erfolgreich ausgewählt'; $string['mumie_form_wiki_link'] = 'Bitte besuchen Sie unser Wiki für weiterführende Informationen!'; $string['mumie_general_duedate'] = 'Allgemeine Abgabefrist:'; @@ -129,8 +129,8 @@ $string['mumie_grade_overridden'] = 'Bewertung erfolgreich gespeichert!'; $string['mumie_grade_percentage'] = 'Bewerung in %'; $string['mumie_grading_settings'] = "Individuelle Bewertungseinstellungen"; +$string['mumie_multi_problem_selector'] = 'Alternativ können Sie mit der Mehrfach-Aufgabenauswahl auch mehrere MUMIE-Aufgaben auf einmal auswählen. Alle Aufgaben werden mit den eingestellten Einstellungen angelegt (Punkte, Frist, Startcontainer etc.). Jede Aufgabe behält ihren eigenen Namen — anders als bei der Einzelauswahl kann kein eigener Name vergeben werden.

Weitere Informationen finden Sie in unserem Wiki'; $string['mumie_multi_tasks_selected'] = '{$a} Tasks ausgewählt:'; -$string['mumie_multi_problem_selector'] ='Alternativ können Sie mit der Mehrfach-Aufgabenauswahl auch mehrere MUMIE-Aufgaben auf einmal auswählen. Alle Aufgaben werden mit den eingestellten Einstellungen angelegt (Punkte, Frist, Startcontainer etc.). Jede Aufgabe behält ihren eigenen Namen — anders als bei der Einzelauswahl kann kein eigener Name vergeben werden.

Weitere Informationen finden Sie in unserem Wiki'; $string['mumie_no_other_task_found'] = 'Keine andere MUMIE Tasks in Kurs gefunden'; $string['mumie_no_submissions'] = 'Keine Antworten abgegeben'; $string['mumie_open_task'] = 'MUMIE-Task öffnen'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 25854b9e..d9c991a2 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -81,8 +81,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_coursefile'] = 'Path to MUMIE course meta file'; -$string['mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline'] = 'Deadline can only be applied to tasks that already have the working period type \'Deadline\' set.'; $string['mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'] = "The selected worksheet cannot have a limited working period.

If you want to limit the working period, please select a worksheet with an appropriate configuration."; +$string['mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline'] = 'Deadline can only be applied to tasks that already have the working period type \'Deadline\' set.'; $string['mumie_form_deadline_required_for_trigger_after_deadline'] = "The selected worksheet requires a limited working period."; $string['mumie_form_due_date_must_be_future'] = 'You must select a date in the future!'; $string['mumie_form_filter'] = 'Filter MUMIE problems'; @@ -111,11 +111,11 @@ $string['mumie_form_task_properties_selection_info'] = 'Select the properties of the current MUMIE Task to apply to other MUMIE Tasks.'; $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.'; -$string['mumie_form_tasks_selection_info'] = 'Choose the MUMIE Tasks you want to apply the selected changes to.'; $string['mumie_form_due_date_multi_edit_hint'] = 'Deadline can only be applied to tasks that were previously created with the working period type \'Deadline\'.'; -$string['mumie_form_working_period_not_duedate_warning'] = 'Working period: not Deadline'; +$string['mumie_form_tasks_selection_info'] = 'Choose the MUMIE Tasks you want to apply the selected changes to.'; $string['mumie_form_title'] = 'Configure MUMIE Server'; $string['mumie_form_topic'] = 'Topic: {$a}'; +$string['mumie_form_working_period_not_duedate_warning'] = 'Working period: not Deadline'; $string['mumie_form_updated_selection'] = 'Successfully selected problem'; $string['mumie_form_wiki_link'] = 'For help and advanced features, please visit our Wiki!'; $string['mumie_general_duedate'] = 'General due date:'; @@ -124,8 +124,8 @@ $string['mumie_grade_overridden'] = 'Updated grade successfully!'; $string['mumie_grade_percentage'] = 'Grade in %'; $string['mumie_grading_settings'] = "Individual grading settings"; +$string['mumie_multi_problem_selector'] = 'Alternatively, you can also create multiple MUMIE Tasks at once using the Multi Problem Selector. All tasks will be created with the settings configured (points, deadline, container type, etc.). Each task keeps its own name — unlike single task creation, no custom name can be assigned.

For more information, have a look at our wiki'; $string['mumie_multi_tasks_selected'] = '{$a} tasks selected:'; -$string['mumie_multi_problem_selector'] ='Alternatively, you can also create multiple MUMIE Tasks at once using the Multi Problem Selector. All tasks will be created with the settings configured (points, deadline, container type, etc.). Each task keeps its own name — unlike single task creation, no custom name can be assigned.

For more information, have a look at our wiki'; $string['mumie_no_other_task_found'] = 'No other MUMIE Tasks found in course'; $string['mumie_no_submissions'] = 'No answers submitted'; $string['mumie_open_task'] = 'Open MUMIE Task'; diff --git a/mod_form.php b/mod_form.php index 8f738d55..cebcbdc3 100644 --- a/mod_form.php +++ b/mod_form.php @@ -149,7 +149,7 @@ private function add_general_fields(MoodleQuickForm $mform, $serveroptions): voi ) ); $mform->addElement('button', 'multi_problem_selector_btn', get_string('mumie_form_multi_prb_selector_btn', 'mod_mumie')); - $mform->addElement('html', ''); + $mform->addElement('html', ''); $mform->addElement('hidden', 'mumie_multi_tasks', ''); $mform->setType('mumie_multi_tasks', PARAM_RAW); diff --git a/styles.css b/styles.css index 2d404650..49d4d744 100644 --- a/styles.css +++ b/styles.css @@ -24,3 +24,10 @@ .mumie_table thead tr th { border-bottom: 1px solid black; } + +#mumie_multi_tasks_summary { + margin: 0.5em 0; + padding: 0.5em; + background: #f0f0f0; + border-radius: 4px; +} From b04b45d96985e1d039770fa8ff2a43b9473fa32b Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 10 Jun 2026 08:41:59 +0200 Subject: [PATCH 060/101] Fix server URL normalization for multi-select task creation --- externallib.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/externallib.php b/externallib.php index f6688eac..dd8d8657 100644 --- a/externallib.php +++ b/externallib.php @@ -154,6 +154,7 @@ public static function create_multiple_tasks($contextid, $section, $tasks, $form require_once($CFG->dirroot . '/course/modlib.php'); require_once($CFG->dirroot . '/mod/mumie/lib.php'); require_once($CFG->dirroot . '/mod/mumie/locallib.php'); + require_once($CFG->dirroot . '/auth/mumie/classes/mumie_server.php'); $params = self::validate_parameters( self::create_multiple_tasks_parameters(), @@ -224,12 +225,15 @@ public static function create_multiple_tasks($contextid, $section, $tasks, $form throw new invalid_parameter_exception('Each task must have a valid link and server'); } + $serverobj = new \auth_mumie\mumie_server(); + $serverobj->set_urlprefix($taskserver); + $moduleinfo->name = clean_param($taskdata['name'] ?? '', PARAM_TEXT); $moduleinfo->language = clean_param($taskdata['language'] ?? '', PARAM_TEXT); $moduleinfo->taskurl = $tasklink . '?lang=' . $moduleinfo->language; $moduleinfo->mumie_coursefile = clean_param($taskdata['path_to_coursefile'] ?? '', PARAM_TEXT); $moduleinfo->mumie_course = clean_param($taskdata['course'] ?? '', PARAM_TEXT); - $moduleinfo->server = $taskserver; + $moduleinfo->server = $serverobj->get_urlprefix(); $moduleinfo->points = $points; $moduleinfo->launchcontainer = $launchcontainer; From 222eff549647678f4f2aeeb89e39cc5da231583a Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Fri, 19 Jun 2026 02:08:01 +0200 Subject: [PATCH 061/101] replace removed core/modal_factory with core/modal_save_cancel --- amd/build/duedate_form.min.js | 2 +- amd/build/duedate_form.min.js.map | 2 +- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/build/view.min.js | 2 +- amd/build/view.min.js.map | 2 +- amd/src/duedate_form.js | 51 +++++++++++++------------------ amd/src/mod_form.js | 2 +- amd/src/view.js | 2 +- 9 files changed, 30 insertions(+), 37 deletions(-) diff --git a/amd/build/duedate_form.min.js b/amd/build/duedate_form.min.js index f4825738..f8cd41a8 100644 --- a/amd/build/duedate_form.min.js +++ b/amd/build/duedate_form.min.js @@ -1,3 +1,3 @@ -define("mod_mumie/duedate_form",["jquery","core/str","core/modal_factory","core/modal_events","core/fragment","core/ajax","core/yui"],(function($,Str,ModalFactory,ModalEvents,Fragment,Ajax,Y){var MumieDueDate=function(selector,contextid,formdata){this.contextid=contextid,this.init(selector,formdata)};return MumieDueDate.prototype.modal=null,MumieDueDate.prototype.contextid=-1,MumieDueDate.prototype.init=function(selector,formdata){const triggers=$(selector);return Str.get_string("mumie_duedate_form","mod_mumie").then(function(title){return ModalFactory.create({type:ModalFactory.types.SAVE_CANCEL,title:title,body:this.getBody(formdata)},triggers)}.bind(this)).then(function(modal){return this.modal=modal,this.modal.setLarge(),this.modal.getRoot().on(ModalEvents.hidden,function(){this.modal.setBody(this.getBody(formdata))}.bind(this)),this.modal.getRoot().on(ModalEvents.save,this.submitForm.bind(this)),this.modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),this.modal}.bind(this))},MumieDueDate.prototype.getBody=function(formdata){void 0===formdata&&(formdata={});var params={jsonformdata:JSON.stringify(formdata)};return Fragment.loadFragment("mod_mumie","new_duedate_form",this.contextid,params)},MumieDueDate.prototype.handleFormSubmissionResponse=function(){this.modal.hide(),Y.use("moodle-core-formchangechecker",(function(){M.core_formchangechecker.reset_form_dirty_state()})),document.location.reload()},MumieDueDate.prototype.handleFormSubmissionFailure=function(data){this.modal.setBody(this.getBody(data))},MumieDueDate.prototype.submitFormAjax=function(e){e.preventDefault();var formData=this.modal.getRoot().find("form").serialize();Ajax.call([{methodname:"mod_mumie_submit_mumieduedate_form",args:{contextid:this.contextid,jsonformdata:JSON.stringify(formData)},done:this.handleFormSubmissionResponse.bind(this,formData),fail:this.handleFormSubmissionFailure.bind(this,formData)}])},MumieDueDate.prototype.submitForm=function(e){e.preventDefault(),this.modal.getRoot().find("form").submit()},{init:function(selector,contextid,formdata){return new MumieDueDate(selector,contextid,formdata)}}})); +define("mod_mumie/duedate_form",["jquery","core/str","core/modal_save_cancel","core/modal_events","core/fragment","core/ajax","core/yui"],(function($,Str,ModalSaveCancel,ModalEvents,Fragment,Ajax,Y){var MumieDueDate=function(selector,contextid,formdata){this.contextid=contextid,this.init(selector,formdata)};return MumieDueDate.prototype.modal=null,MumieDueDate.prototype.contextid=-1,MumieDueDate.prototype.init=function(selector,formdata){$(selector).on("click",function(e){return e.preventDefault(),Str.get_string("mumie_duedate_form","mod_mumie").then(function(title){return ModalSaveCancel.create({title:title,body:this.getBody(formdata),large:!0,removeOnClose:!0})}.bind(this)).then(function(modal){return this.modal=modal,modal.getRoot().on(ModalEvents.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),modal.show(),modal}.bind(this))}.bind(this))},MumieDueDate.prototype.getBody=function(formdata){void 0===formdata&&(formdata={});var params={jsonformdata:JSON.stringify(formdata)};return Fragment.loadFragment("mod_mumie","new_duedate_form",this.contextid,params)},MumieDueDate.prototype.handleFormSubmissionResponse=function(){this.modal.hide(),Y.use("moodle-core-formchangechecker",(function(){M.core_formchangechecker.reset_form_dirty_state()})),document.location.reload()},MumieDueDate.prototype.handleFormSubmissionFailure=function(data){this.modal.setBody(this.getBody(data))},MumieDueDate.prototype.submitFormAjax=function(e){e.preventDefault();var formData=this.modal.getRoot().find("form").serialize();Ajax.call([{methodname:"mod_mumie_submit_mumieduedate_form",args:{contextid:this.contextid,jsonformdata:JSON.stringify(formData)},done:this.handleFormSubmissionResponse.bind(this,formData),fail:this.handleFormSubmissionFailure.bind(this,formData)}])},MumieDueDate.prototype.submitForm=function(e){e.preventDefault(),this.modal.getRoot().find("form").submit()},{init:function(selector,contextid,formdata){return new MumieDueDate(selector,contextid,formdata)}}})); //# sourceMappingURL=duedate_form.min.js.map \ No newline at end of file diff --git a/amd/build/duedate_form.min.js.map b/amd/build/duedate_form.min.js.map index c1f541a2..b7cd1090 100644 --- a/amd/build/duedate_form.min.js.map +++ b/amd/build/duedate_form.min.js.map @@ -1 +1 @@ -{"version":3,"file":"duedate_form.min.js","sources":["../src/duedate_form.js"],"sourcesContent":["define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/fragment', 'core/ajax', 'core/yui'],\n function($, Str, ModalFactory, ModalEvents, Fragment, Ajax, Y) {\n\n var MumieDueDate = function(selector, contextid, formdata) {\n this.contextid = contextid;\n this.init(selector, formdata);\n };\n\n MumieDueDate.prototype.modal = null;\n\n MumieDueDate.prototype.contextid = -1;\n\n MumieDueDate.prototype.init = function(selector, formdata) {\n const triggers = $(selector);\n return Str.get_string('mumie_duedate_form', 'mod_mumie').then(function(title) {\n // Create the modal.\n return ModalFactory.create({\n type: ModalFactory.types.SAVE_CANCEL,\n title: title,\n body: this.getBody(formdata)\n }, triggers);\n }.bind(this)).then(function(modal) {\n // Keep a reference to the modal.\n this.modal = modal;\n\n // Forms are big, we want a big modal.\n this.modal.setLarge();\n\n // We want to reset the form every time it is opened.\n this.modal.getRoot().on(ModalEvents.hidden, function() {\n this.modal.setBody(this.getBody(formdata));\n }.bind(this));\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n this.modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n this.modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n return this.modal;\n\n }.bind(this));\n };\n\n /**\n * @method getBody\n * @private\n * @param {Object} formdata\n * @return {Promise}\n */\n MumieDueDate.prototype.getBody = function(formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n // Get the content of the modal.\n var params = {\n jsonformdata: JSON.stringify(formdata)\n };\n return Fragment.loadFragment('mod_mumie', 'new_duedate_form', this.contextid, params);\n };\n\n /**\n * @method handleFormSubmissionResponse\n * @private\n */\n MumieDueDate.prototype.handleFormSubmissionResponse = function() {\n this.modal.hide();\n // We could trigger an event instead.\n // Yuk.\n Y.use('moodle-core-formchangechecker', function() {\n M.core_formchangechecker.reset_form_dirty_state();\n });\n\n document.location.reload();\n };\n\n /**\n * @method handleFormSubmissionFailure\n * @private\n * @param {Object} data\n */\n MumieDueDate.prototype.handleFormSubmissionFailure = function(data) {\n // Oh noes! Epic fail :(\n // Ah wait - this is normal. We need to re-display the form with errors!\n this.modal.setBody(this.getBody(data));\n };\n\n /**\n * Private method\n *\n * @method submitFormAjax\n * @private\n * @param {Event} e Form submission event.\n */\n MumieDueDate.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialized string.\n var formData = this.modal.getRoot().find('form').serialize();\n // Now we can continue...\n Ajax.call([{\n methodname: 'mod_mumie_submit_mumieduedate_form',\n args: {\n contextid: this.contextid,\n jsonformdata: JSON.stringify(formData)\n },\n done: this.handleFormSubmissionResponse.bind(this, formData),\n fail: this.handleFormSubmissionFailure.bind(this, formData)\n }]);\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n MumieDueDate.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n return /** @alias module:mod_mumie/newduedate */ {\n // Public variables and functions.\n /**\n * Attach event listeners to initialize this module.\n *\n * @method init\n * @param {string} selector The CSS selector used to find nodes that will trigger this module.\n * @param {int} contextid The contextid for the course.\n * @param {Object} formdata\n * @return {Promise}\n */\n init: function(selector, contextid, formdata) {\n return new MumieDueDate(selector, contextid, formdata);\n }\n };\n\n });"],"names":["define","$","Str","ModalFactory","ModalEvents","Fragment","Ajax","Y","MumieDueDate","selector","contextid","formdata","init","prototype","modal","triggers","get_string","then","title","create","type","types","SAVE_CANCEL","body","this","getBody","bind","setLarge","getRoot","on","hidden","setBody","save","submitForm","submitFormAjax","params","jsonformdata","JSON","stringify","loadFragment","handleFormSubmissionResponse","hide","use","M","core_formchangechecker","reset_form_dirty_state","document","location","reload","handleFormSubmissionFailure","data","e","preventDefault","formData","find","serialize","call","methodname","args","done","fail","submit"],"mappings":"AAAAA,gCAAO,CAAC,SAAU,WAAY,qBAAsB,oBAAqB,gBAAiB,YAAa,aACnG,SAASC,EAAGC,IAAKC,aAAcC,YAAaC,SAAUC,KAAMC,OAEpDC,aAAe,SAASC,SAAUC,UAAWC,eACxCD,UAAYA,eACZE,KAAKH,SAAUE,kBAGxBH,aAAaK,UAAUC,MAAQ,KAE/BN,aAAaK,UAAUH,WAAa,EAEpCF,aAAaK,UAAUD,KAAO,SAASH,SAAUE,gBACvCI,SAAWd,EAAEQ,iBACZP,IAAIc,WAAW,qBAAsB,aAAaC,KAAK,SAASC,cAE5Df,aAAagB,OAAO,CACvBC,KAAMjB,aAAakB,MAAMC,YACzBJ,MAAOA,MACPK,KAAMC,KAAKC,QAAQd,WACpBI,WACLW,KAAKF,OAAOP,KAAK,SAASH,mBAEnBA,MAAQA,WAGRA,MAAMa,gBAGNb,MAAMc,UAAUC,GAAGzB,YAAY0B,OAAQ,gBACnChB,MAAMiB,QAAQP,KAAKC,QAAQd,YAClCe,KAAKF,YAIFV,MAAMc,UAAUC,GAAGzB,YAAY4B,KAAMR,KAAKS,WAAWP,KAAKF,YAE1DV,MAAMc,UAAUC,GAAG,SAAU,OAAQL,KAAKU,eAAeR,KAAKF,OAE5DA,KAAKV,OAEdY,KAAKF,QASXhB,aAAaK,UAAUY,QAAU,SAASd,eACd,IAAbA,WACPA,SAAW,QAGXwB,OAAS,CACTC,aAAcC,KAAKC,UAAU3B,kBAE1BN,SAASkC,aAAa,YAAa,mBAAoBf,KAAKd,UAAWyB,SAOlF3B,aAAaK,UAAU2B,6BAA+B,gBAC7C1B,MAAM2B,OAGXlC,EAAEmC,IAAI,iCAAiC,WACnCC,EAAEC,uBAAuBC,4BAG7BC,SAASC,SAASC,UAQtBxC,aAAaK,UAAUoC,4BAA8B,SAASC,WAGrDpC,MAAMiB,QAAQP,KAAKC,QAAQyB,QAUpC1C,aAAaK,UAAUqB,eAAiB,SAASiB,GAE7CA,EAAEC,qBAGEC,SAAW7B,KAAKV,MAAMc,UAAU0B,KAAK,QAAQC,YAEjDjD,KAAKkD,KAAK,CAAC,CACPC,WAAY,qCACZC,KAAM,CACFhD,UAAWc,KAAKd,UAChB0B,aAAcC,KAAKC,UAAUe,WAEjCM,KAAMnC,KAAKgB,6BAA6Bd,KAAKF,KAAM6B,UACnDO,KAAMpC,KAAKyB,4BAA4BvB,KAAKF,KAAM6B,cAW1D7C,aAAaK,UAAUoB,WAAa,SAASkB,GACzCA,EAAEC,sBACGtC,MAAMc,UAAU0B,KAAK,QAAQO,UAGW,CAW7CjD,KAAM,SAASH,SAAUC,UAAWC,iBACzB,IAAIH,aAAaC,SAAUC,UAAWC"} \ No newline at end of file +{"version":3,"file":"duedate_form.min.js","sources":["../src/duedate_form.js"],"sourcesContent":["define(['jquery', 'core/str', 'core/modal_save_cancel', 'core/modal_events', 'core/fragment', 'core/ajax', 'core/yui'],\n function($, Str, ModalSaveCancel, ModalEvents, Fragment, Ajax, Y) {\n\n var MumieDueDate = function(selector, contextid, formdata) {\n this.contextid = contextid;\n this.init(selector, formdata);\n };\n\n MumieDueDate.prototype.modal = null;\n\n MumieDueDate.prototype.contextid = -1;\n\n MumieDueDate.prototype.init = function(selector, formdata) {\n $(selector).on('click', function(e) {\n e.preventDefault();\n return Str.get_string('mumie_duedate_form', 'mod_mumie').then(function(title) {\n return ModalSaveCancel.create({\n title: title,\n body: this.getBody(formdata),\n large: true,\n removeOnClose: true,\n });\n }.bind(this)).then(function(modal) {\n this.modal = modal;\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n modal.show();\n return modal;\n }.bind(this));\n }.bind(this));\n };\n\n /**\n * @method getBody\n * @private\n * @param {Object} formdata\n * @return {Promise}\n */\n MumieDueDate.prototype.getBody = function(formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n // Get the content of the modal.\n var params = {\n jsonformdata: JSON.stringify(formdata)\n };\n return Fragment.loadFragment('mod_mumie', 'new_duedate_form', this.contextid, params);\n };\n\n /**\n * @method handleFormSubmissionResponse\n * @private\n */\n MumieDueDate.prototype.handleFormSubmissionResponse = function() {\n this.modal.hide();\n // We could trigger an event instead.\n // Yuk.\n Y.use('moodle-core-formchangechecker', function() {\n M.core_formchangechecker.reset_form_dirty_state();\n });\n\n document.location.reload();\n };\n\n /**\n * @method handleFormSubmissionFailure\n * @private\n * @param {Object} data\n */\n MumieDueDate.prototype.handleFormSubmissionFailure = function(data) {\n // Oh noes! Epic fail :(\n // Ah wait - this is normal. We need to re-display the form with errors!\n this.modal.setBody(this.getBody(data));\n };\n\n /**\n * Private method\n *\n * @method submitFormAjax\n * @private\n * @param {Event} e Form submission event.\n */\n MumieDueDate.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialized string.\n var formData = this.modal.getRoot().find('form').serialize();\n // Now we can continue...\n Ajax.call([{\n methodname: 'mod_mumie_submit_mumieduedate_form',\n args: {\n contextid: this.contextid,\n jsonformdata: JSON.stringify(formData)\n },\n done: this.handleFormSubmissionResponse.bind(this, formData),\n fail: this.handleFormSubmissionFailure.bind(this, formData)\n }]);\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n MumieDueDate.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n return /** @alias module:mod_mumie/newduedate */ {\n // Public variables and functions.\n /**\n * Attach event listeners to initialize this module.\n *\n * @method init\n * @param {string} selector The CSS selector used to find nodes that will trigger this module.\n * @param {int} contextid The contextid for the course.\n * @param {Object} formdata\n * @return {Promise}\n */\n init: function(selector, contextid, formdata) {\n return new MumieDueDate(selector, contextid, formdata);\n }\n };\n\n });"],"names":["define","$","Str","ModalSaveCancel","ModalEvents","Fragment","Ajax","Y","MumieDueDate","selector","contextid","formdata","init","prototype","modal","on","e","preventDefault","get_string","then","title","create","body","this","getBody","large","removeOnClose","bind","getRoot","save","submitForm","submitFormAjax","show","params","jsonformdata","JSON","stringify","loadFragment","handleFormSubmissionResponse","hide","use","M","core_formchangechecker","reset_form_dirty_state","document","location","reload","handleFormSubmissionFailure","data","setBody","formData","find","serialize","call","methodname","args","done","fail","submit"],"mappings":"AAAAA,gCAAO,CAAC,SAAU,WAAY,yBAA0B,oBAAqB,gBAAiB,YAAa,aACvG,SAASC,EAAGC,IAAKC,gBAAiBC,YAAaC,SAAUC,KAAMC,OAEvDC,aAAe,SAASC,SAAUC,UAAWC,eACxCD,UAAYA,eACZE,KAAKH,SAAUE,kBAGxBH,aAAaK,UAAUC,MAAQ,KAE/BN,aAAaK,UAAUH,WAAa,EAEpCF,aAAaK,UAAUD,KAAO,SAASH,SAAUE,UAC7CV,EAAEQ,UAAUM,GAAG,QAAS,SAASC,UAC7BA,EAAEC,iBACKf,IAAIgB,WAAW,qBAAsB,aAAaC,KAAK,SAASC,cAC5DjB,gBAAgBkB,OAAO,CAC1BD,MAAOA,MACPE,KAAMC,KAAKC,QAAQb,UACnBc,OAAO,EACPC,eAAe,KAErBC,KAAKJ,OAAOJ,KAAK,SAASL,mBACnBA,MAAQA,MAIbA,MAAMc,UAAUb,GAAGX,YAAYyB,KAAMN,KAAKO,WAAWH,KAAKJ,OAE1DT,MAAMc,UAAUb,GAAG,SAAU,OAAQQ,KAAKQ,eAAeJ,KAAKJ,OAE9DT,MAAMkB,OACClB,OACTa,KAAKJ,QACTI,KAAKJ,QASXf,aAAaK,UAAUW,QAAU,SAASb,eACd,IAAbA,WACPA,SAAW,QAGXsB,OAAS,CACTC,aAAcC,KAAKC,UAAUzB,kBAE1BN,SAASgC,aAAa,YAAa,mBAAoBd,KAAKb,UAAWuB,SAOlFzB,aAAaK,UAAUyB,6BAA+B,gBAC7CxB,MAAMyB,OAGXhC,EAAEiC,IAAI,iCAAiC,WACnCC,EAAEC,uBAAuBC,4BAG7BC,SAASC,SAASC,UAQtBtC,aAAaK,UAAUkC,4BAA8B,SAASC,WAGrDlC,MAAMmC,QAAQ1B,KAAKC,QAAQwB,QAUpCxC,aAAaK,UAAUkB,eAAiB,SAASf,GAE7CA,EAAEC,qBAGEiC,SAAW3B,KAAKT,MAAMc,UAAUuB,KAAK,QAAQC,YAEjD9C,KAAK+C,KAAK,CAAC,CACPC,WAAY,qCACZC,KAAM,CACF7C,UAAWa,KAAKb,UAChBwB,aAAcC,KAAKC,UAAUc,WAEjCM,KAAMjC,KAAKe,6BAA6BX,KAAKJ,KAAM2B,UACnDO,KAAMlC,KAAKwB,4BAA4BpB,KAAKJ,KAAM2B,cAW1D1C,aAAaK,UAAUiB,WAAa,SAASd,GACzCA,EAAEC,sBACGH,MAAMc,UAAUuB,KAAK,QAAQO,UAGW,CAW7C9C,KAAM,SAASH,SAAUC,UAAWC,iBACzB,IAAIH,aAAaC,SAAUC,UAAWC"} \ No newline at end of file diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 87bdacf1..58c09de2 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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","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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data),isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function buildURL(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;var selectedServerUrl;return(selectedServerUrl=selectedServer,new URL(lmsSelectorUrl).origin===new URL(selectedServerUrl).origin)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_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)+"&gradingType=all","_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.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 fdb21230..f40461e6 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","forEach","checkbox","push","filter","duedateSelected","Array","from","some","querySelectorAll","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","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', '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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 '&gradingType=all',\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","taskController","setSelection","link","setIsGraded","worksheetController","setWorksheet","focus","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","selectedServerUrl","URL","encodeURIComponent","getSelectedLanguage","location","onclick","open","onclose","e","preventDefault","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","updateName","updateGradeEditability","includes","split","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","forEach","checkbox","push","filter","duedateSelected","Array","from","some","querySelectorAll","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","length","MumieServer"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/view.min.js b/amd/build/view.min.js index ef3bc370..7465ea24 100644 --- a/amd/build/view.min.js +++ b/amd/build/view.min.js @@ -1,3 +1,3 @@ -define("mod_mumie/view",["jquery","core/templates","core/modal_factory","mod_mumie/duedate_form"],(function($){return{init:function(contextid){!function(contextid){const addBtns=$(".mumie_duedate_add_btn");addBtns.each((function(i){const btn=addBtns[i],data=JSON.parse(btn.children[1].textContent),formdata="&_qf__duedate_form=1&userid="+data.userid+"&mumie="+data.mumie;require(["mod_mumie/duedate_form"],(function(MumieDueDate){MumieDueDate.init(btn,contextid,formdata)}))}))}(contextid),function(contextid){const editBtns=$(".mumie_duedate_edit_btn");editBtns.each((function(i){const btn=editBtns[i],data=JSON.parse(btn.children[1].textContent),formdata="id="+data.id+"&_qf__duedate_form=1&userid="+data.userid+"&mumie="+data.mumie+"&duedate="+data.duedate;require(["mod_mumie/duedate_form"],(function(MumieDueDate){MumieDueDate.init(btn,contextid,formdata)}))}))}(contextid)}}})); +define("mod_mumie/view",["jquery","core/templates","mod_mumie/duedate_form"],(function($){return{init:function(contextid){!function(contextid){const addBtns=$(".mumie_duedate_add_btn");addBtns.each((function(i){const btn=addBtns[i],data=JSON.parse(btn.children[1].textContent),formdata="&_qf__duedate_form=1&userid="+data.userid+"&mumie="+data.mumie;require(["mod_mumie/duedate_form"],(function(MumieDueDate){MumieDueDate.init(btn,contextid,formdata)}))}))}(contextid),function(contextid){const editBtns=$(".mumie_duedate_edit_btn");editBtns.each((function(i){const btn=editBtns[i],data=JSON.parse(btn.children[1].textContent),formdata="id="+data.id+"&_qf__duedate_form=1&userid="+data.userid+"&mumie="+data.mumie+"&duedate="+data.duedate;require(["mod_mumie/duedate_form"],(function(MumieDueDate){MumieDueDate.init(btn,contextid,formdata)}))}))}(contextid)}}})); //# sourceMappingURL=view.min.js.map \ No newline at end of file diff --git a/amd/build/view.min.js.map b/amd/build/view.min.js.map index 5feb4aa6..527937d4 100644 --- a/amd/build/view.min.js.map +++ b/amd/build/view.min.js.map @@ -1 +1 @@ -{"version":3,"file":"view.min.js","sources":["../src/view.js"],"sourcesContent":["define(['jquery', 'core/templates', 'core/modal_factory', 'mod_mumie/duedate_form'],\n function($) {\n return {\n init: function(contextid) {\n setAddDuedateListeners(contextid);\n setEditDuedateListeners(contextid);\n }\n };\n\n /**\n * Set click listener to add a server button\n * @param {number} contextid\n */\n function setAddDuedateListeners(contextid) {\n const addBtns = $(\".mumie_duedate_add_btn\");\n\n addBtns.each(function(i) {\n const btn = addBtns[i];\n const data = JSON.parse(btn.children[1].textContent);\n const formdata = \"&_qf__duedate_form=1&userid=\" + data.userid + \"&mumie=\" + data.mumie;\n require(['mod_mumie/duedate_form'], function(MumieDueDate) {\n MumieDueDate.init(btn, contextid, formdata);\n });\n });\n }\n\n /**\n * Set click listeners for the edit buttons\n * @param {number} contextid\n */\n function setEditDuedateListeners(contextid) {\n const editBtns = $(\".mumie_duedate_edit_btn\");\n\n editBtns.each(function(i) {\n const btn = editBtns[i];\n const data = JSON.parse(btn.children[1].textContent);\n const formdata = \"id=\" + data.id +\n \"&_qf__duedate_form=1&userid=\" + data.userid + \"&mumie=\" + data.mumie + \"&duedate=\" + data.duedate;\n require(['mod_mumie/duedate_form'], function(MumieDueDate) {\n MumieDueDate.init(btn, contextid, formdata);\n });\n });\n }\n });"],"names":["define","$","init","contextid","addBtns","each","i","btn","data","JSON","parse","children","textContent","formdata","userid","mumie","require","MumieDueDate","setAddDuedateListeners","editBtns","id","duedate","setEditDuedateListeners"],"mappings":"AAAAA,wBAAO,CAAC,SAAU,iBAAkB,qBAAsB,2BACtD,SAASC,SACE,CACHC,KAAM,SAASC,qBAUaA,iBACtBC,QAAUH,EAAE,0BAElBG,QAAQC,MAAK,SAASC,SACZC,IAAMH,QAAQE,GACdE,KAAOC,KAAKC,MAAMH,IAAII,SAAS,GAAGC,aAClCC,SAAW,+BAAiCL,KAAKM,OAAS,UAAYN,KAAKO,MACjFC,QAAQ,CAAC,2BAA2B,SAASC,cACzCA,aAAaf,KAAKK,IAAKJ,UAAWU,gBAjBtCK,CAAuBf,oBA0BEA,iBACvBgB,SAAWlB,EAAE,2BAEnBkB,SAASd,MAAK,SAASC,SACbC,IAAMY,SAASb,GACfE,KAAOC,KAAKC,MAAMH,IAAII,SAAS,GAAGC,aAClCC,SAAW,MAAQL,KAAKY,GAC1B,+BAAiCZ,KAAKM,OAAS,UAAYN,KAAKO,MAAQ,YAAcP,KAAKa,QAC/FL,QAAQ,CAAC,2BAA2B,SAASC,cACzCA,aAAaf,KAAKK,IAAKJ,UAAWU,gBAlCtCS,CAAwBnB"} \ No newline at end of file +{"version":3,"file":"view.min.js","sources":["../src/view.js"],"sourcesContent":["define(['jquery', 'core/templates', 'mod_mumie/duedate_form'],\n function($) {\n return {\n init: function(contextid) {\n setAddDuedateListeners(contextid);\n setEditDuedateListeners(contextid);\n }\n };\n\n /**\n * Set click listener to add a server button\n * @param {number} contextid\n */\n function setAddDuedateListeners(contextid) {\n const addBtns = $(\".mumie_duedate_add_btn\");\n\n addBtns.each(function(i) {\n const btn = addBtns[i];\n const data = JSON.parse(btn.children[1].textContent);\n const formdata = \"&_qf__duedate_form=1&userid=\" + data.userid + \"&mumie=\" + data.mumie;\n require(['mod_mumie/duedate_form'], function(MumieDueDate) {\n MumieDueDate.init(btn, contextid, formdata);\n });\n });\n }\n\n /**\n * Set click listeners for the edit buttons\n * @param {number} contextid\n */\n function setEditDuedateListeners(contextid) {\n const editBtns = $(\".mumie_duedate_edit_btn\");\n\n editBtns.each(function(i) {\n const btn = editBtns[i];\n const data = JSON.parse(btn.children[1].textContent);\n const formdata = \"id=\" + data.id +\n \"&_qf__duedate_form=1&userid=\" + data.userid + \"&mumie=\" + data.mumie + \"&duedate=\" + data.duedate;\n require(['mod_mumie/duedate_form'], function(MumieDueDate) {\n MumieDueDate.init(btn, contextid, formdata);\n });\n });\n }\n });"],"names":["define","$","init","contextid","addBtns","each","i","btn","data","JSON","parse","children","textContent","formdata","userid","mumie","require","MumieDueDate","setAddDuedateListeners","editBtns","id","duedate","setEditDuedateListeners"],"mappings":"AAAAA,wBAAO,CAAC,SAAU,iBAAkB,2BAChC,SAASC,SACE,CACHC,KAAM,SAASC,qBAUaA,iBACtBC,QAAUH,EAAE,0BAElBG,QAAQC,MAAK,SAASC,SACZC,IAAMH,QAAQE,GACdE,KAAOC,KAAKC,MAAMH,IAAII,SAAS,GAAGC,aAClCC,SAAW,+BAAiCL,KAAKM,OAAS,UAAYN,KAAKO,MACjFC,QAAQ,CAAC,2BAA2B,SAASC,cACzCA,aAAaf,KAAKK,IAAKJ,UAAWU,gBAjBtCK,CAAuBf,oBA0BEA,iBACvBgB,SAAWlB,EAAE,2BAEnBkB,SAASd,MAAK,SAASC,SACbC,IAAMY,SAASb,GACfE,KAAOC,KAAKC,MAAMH,IAAII,SAAS,GAAGC,aAClCC,SAAW,MAAQL,KAAKY,GAC1B,+BAAiCZ,KAAKM,OAAS,UAAYN,KAAKO,MAAQ,YAAcP,KAAKa,QAC/FL,QAAQ,CAAC,2BAA2B,SAASC,cACzCA,aAAaf,KAAKK,IAAKJ,UAAWU,gBAlCtCS,CAAwBnB"} \ No newline at end of file diff --git a/amd/src/duedate_form.js b/amd/src/duedate_form.js index 80316221..118f2929 100644 --- a/amd/src/duedate_form.js +++ b/amd/src/duedate_form.js @@ -1,5 +1,5 @@ -define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/fragment', 'core/ajax', 'core/yui'], - function($, Str, ModalFactory, ModalEvents, Fragment, Ajax, Y) { +define(['jquery', 'core/str', 'core/modal_save_cancel', 'core/modal_events', 'core/fragment', 'core/ajax', 'core/yui'], + function($, Str, ModalSaveCancel, ModalEvents, Fragment, Ajax, Y) { var MumieDueDate = function(selector, contextid, formdata) { this.contextid = contextid; @@ -11,34 +11,27 @@ define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/f MumieDueDate.prototype.contextid = -1; MumieDueDate.prototype.init = function(selector, formdata) { - const triggers = $(selector); - return Str.get_string('mumie_duedate_form', 'mod_mumie').then(function(title) { - // Create the modal. - return ModalFactory.create({ - type: ModalFactory.types.SAVE_CANCEL, - title: title, - body: this.getBody(formdata) - }, triggers); - }.bind(this)).then(function(modal) { - // Keep a reference to the modal. - this.modal = modal; - - // Forms are big, we want a big modal. - this.modal.setLarge(); - - // We want to reset the form every time it is opened. - this.modal.getRoot().on(ModalEvents.hidden, function() { - this.modal.setBody(this.getBody(formdata)); + $(selector).on('click', function(e) { + e.preventDefault(); + return Str.get_string('mumie_duedate_form', 'mod_mumie').then(function(title) { + return ModalSaveCancel.create({ + title: title, + body: this.getBody(formdata), + large: true, + removeOnClose: true, + }); + }.bind(this)).then(function(modal) { + this.modal = modal; + + // We catch the modal save event, and use it to submit the form inside the modal. + // Triggering a form submission will give JS validation scripts a chance to check for errors. + modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this)); + // We also catch the form submit event and use it to submit the form with ajax. + modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this)); + + modal.show(); + return modal; }.bind(this)); - - // We catch the modal save event, and use it to submit the form inside the modal. - // Triggering a form submission will give JS validation scripts a chance to check for errors. - this.modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this)); - // We also catch the form submit event and use it to submit the form with ajax. - this.modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this)); - - return this.modal; - }.bind(this)); }; diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 1e43c90b..1faa9c41 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -1,4 +1,4 @@ -define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_server_config', 'core/ajax'], +define(['jquery', 'core/templates', 'auth_mumie/mumie_server_config', 'core/ajax'], function() { const addServerButton = document.getElementById("id_add_server_button"); const missingConfig = document.getElementsByName("mumie_missing_config")[0]; diff --git a/amd/src/view.js b/amd/src/view.js index 32d1db10..22f36665 100644 --- a/amd/src/view.js +++ b/amd/src/view.js @@ -1,4 +1,4 @@ -define(['jquery', 'core/templates', 'core/modal_factory', 'mod_mumie/duedate_form'], +define(['jquery', 'core/templates', 'mod_mumie/duedate_form'], function($) { return { init: function(contextid) { From efd3a78a116a7cdb046c02f3349ed2da5eae4539 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Fri, 19 Jun 2026 02:52:51 +0200 Subject: [PATCH 062/101] replace removed moodle-core-formchangechecker yui module with core_form/changechecker --- amd/build/duedate_form.min.js | 2 +- amd/build/duedate_form.min.js.map | 2 +- amd/src/duedate_form.js | 18 ++++++++++-------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/amd/build/duedate_form.min.js b/amd/build/duedate_form.min.js index f8cd41a8..366ade3a 100644 --- a/amd/build/duedate_form.min.js +++ b/amd/build/duedate_form.min.js @@ -1,3 +1,3 @@ -define("mod_mumie/duedate_form",["jquery","core/str","core/modal_save_cancel","core/modal_events","core/fragment","core/ajax","core/yui"],(function($,Str,ModalSaveCancel,ModalEvents,Fragment,Ajax,Y){var MumieDueDate=function(selector,contextid,formdata){this.contextid=contextid,this.init(selector,formdata)};return MumieDueDate.prototype.modal=null,MumieDueDate.prototype.contextid=-1,MumieDueDate.prototype.init=function(selector,formdata){$(selector).on("click",function(e){return e.preventDefault(),Str.get_string("mumie_duedate_form","mod_mumie").then(function(title){return ModalSaveCancel.create({title:title,body:this.getBody(formdata),large:!0,removeOnClose:!0})}.bind(this)).then(function(modal){return this.modal=modal,modal.getRoot().on(ModalEvents.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),modal.show(),modal}.bind(this))}.bind(this))},MumieDueDate.prototype.getBody=function(formdata){void 0===formdata&&(formdata={});var params={jsonformdata:JSON.stringify(formdata)};return Fragment.loadFragment("mod_mumie","new_duedate_form",this.contextid,params)},MumieDueDate.prototype.handleFormSubmissionResponse=function(){this.modal.hide(),Y.use("moodle-core-formchangechecker",(function(){M.core_formchangechecker.reset_form_dirty_state()})),document.location.reload()},MumieDueDate.prototype.handleFormSubmissionFailure=function(data){this.modal.setBody(this.getBody(data))},MumieDueDate.prototype.submitFormAjax=function(e){e.preventDefault();var formData=this.modal.getRoot().find("form").serialize();Ajax.call([{methodname:"mod_mumie_submit_mumieduedate_form",args:{contextid:this.contextid,jsonformdata:JSON.stringify(formData)},done:this.handleFormSubmissionResponse.bind(this,formData),fail:this.handleFormSubmissionFailure.bind(this,formData)}])},MumieDueDate.prototype.submitForm=function(e){e.preventDefault(),this.modal.getRoot().find("form").submit()},{init:function(selector,contextid,formdata){return new MumieDueDate(selector,contextid,formdata)}}})); +define("mod_mumie/duedate_form",["jquery","core/str","core/modal_save_cancel","core/modal_events","core/fragment","core/ajax","core_form/changechecker"],(function($,Str,ModalSaveCancel,ModalEvents,Fragment,Ajax,FormChangeChecker){var MumieDueDate=function(selector,contextid,formdata){this.contextid=contextid,this.init(selector,formdata)};return MumieDueDate.prototype.modal=null,MumieDueDate.prototype.contextid=-1,MumieDueDate.prototype.init=function(selector,formdata){$(selector).on("click",function(e){return e.preventDefault(),Str.get_string("mumie_duedate_form","mod_mumie").then(function(title){return ModalSaveCancel.create({title:title,body:this.getBody(formdata),large:!0,removeOnClose:!0})}.bind(this)).then(function(modal){return this.modal=modal,modal.getRoot().on(ModalEvents.save,this.submitForm.bind(this)),modal.getRoot().on("submit","form",this.submitFormAjax.bind(this)),modal.show(),modal}.bind(this))}.bind(this))},MumieDueDate.prototype.getBody=function(formdata){void 0===formdata&&(formdata={});var params={jsonformdata:JSON.stringify(formdata)};return Fragment.loadFragment("mod_mumie","new_duedate_form",this.contextid,params)},MumieDueDate.prototype.handleFormSubmissionResponse=function(){this.modal.hide(),FormChangeChecker.resetAllFormDirtyStates(),document.location.reload()},MumieDueDate.prototype.handleFormSubmissionFailure=function(data){this.modal.setBody(this.getBody(data))},MumieDueDate.prototype.submitFormAjax=function(e){e.preventDefault();var formData=this.modal.getRoot().find("form").serialize();Ajax.call([{methodname:"mod_mumie_submit_mumieduedate_form",args:{contextid:this.contextid,jsonformdata:JSON.stringify(formData)},done:this.handleFormSubmissionResponse.bind(this,formData),fail:this.handleFormSubmissionFailure.bind(this,formData)}])},MumieDueDate.prototype.submitForm=function(e){e.preventDefault(),this.modal.getRoot().find("form").submit()},{init:function(selector,contextid,formdata){return new MumieDueDate(selector,contextid,formdata)}}})); //# sourceMappingURL=duedate_form.min.js.map \ No newline at end of file diff --git a/amd/build/duedate_form.min.js.map b/amd/build/duedate_form.min.js.map index b7cd1090..39a38f30 100644 --- a/amd/build/duedate_form.min.js.map +++ b/amd/build/duedate_form.min.js.map @@ -1 +1 @@ -{"version":3,"file":"duedate_form.min.js","sources":["../src/duedate_form.js"],"sourcesContent":["define(['jquery', 'core/str', 'core/modal_save_cancel', 'core/modal_events', 'core/fragment', 'core/ajax', 'core/yui'],\n function($, Str, ModalSaveCancel, ModalEvents, Fragment, Ajax, Y) {\n\n var MumieDueDate = function(selector, contextid, formdata) {\n this.contextid = contextid;\n this.init(selector, formdata);\n };\n\n MumieDueDate.prototype.modal = null;\n\n MumieDueDate.prototype.contextid = -1;\n\n MumieDueDate.prototype.init = function(selector, formdata) {\n $(selector).on('click', function(e) {\n e.preventDefault();\n return Str.get_string('mumie_duedate_form', 'mod_mumie').then(function(title) {\n return ModalSaveCancel.create({\n title: title,\n body: this.getBody(formdata),\n large: true,\n removeOnClose: true,\n });\n }.bind(this)).then(function(modal) {\n this.modal = modal;\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n modal.show();\n return modal;\n }.bind(this));\n }.bind(this));\n };\n\n /**\n * @method getBody\n * @private\n * @param {Object} formdata\n * @return {Promise}\n */\n MumieDueDate.prototype.getBody = function(formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n // Get the content of the modal.\n var params = {\n jsonformdata: JSON.stringify(formdata)\n };\n return Fragment.loadFragment('mod_mumie', 'new_duedate_form', this.contextid, params);\n };\n\n /**\n * @method handleFormSubmissionResponse\n * @private\n */\n MumieDueDate.prototype.handleFormSubmissionResponse = function() {\n this.modal.hide();\n // We could trigger an event instead.\n // Yuk.\n Y.use('moodle-core-formchangechecker', function() {\n M.core_formchangechecker.reset_form_dirty_state();\n });\n\n document.location.reload();\n };\n\n /**\n * @method handleFormSubmissionFailure\n * @private\n * @param {Object} data\n */\n MumieDueDate.prototype.handleFormSubmissionFailure = function(data) {\n // Oh noes! Epic fail :(\n // Ah wait - this is normal. We need to re-display the form with errors!\n this.modal.setBody(this.getBody(data));\n };\n\n /**\n * Private method\n *\n * @method submitFormAjax\n * @private\n * @param {Event} e Form submission event.\n */\n MumieDueDate.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialized string.\n var formData = this.modal.getRoot().find('form').serialize();\n // Now we can continue...\n Ajax.call([{\n methodname: 'mod_mumie_submit_mumieduedate_form',\n args: {\n contextid: this.contextid,\n jsonformdata: JSON.stringify(formData)\n },\n done: this.handleFormSubmissionResponse.bind(this, formData),\n fail: this.handleFormSubmissionFailure.bind(this, formData)\n }]);\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n MumieDueDate.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n return /** @alias module:mod_mumie/newduedate */ {\n // Public variables and functions.\n /**\n * Attach event listeners to initialize this module.\n *\n * @method init\n * @param {string} selector The CSS selector used to find nodes that will trigger this module.\n * @param {int} contextid The contextid for the course.\n * @param {Object} formdata\n * @return {Promise}\n */\n init: function(selector, contextid, formdata) {\n return new MumieDueDate(selector, contextid, formdata);\n }\n };\n\n });"],"names":["define","$","Str","ModalSaveCancel","ModalEvents","Fragment","Ajax","Y","MumieDueDate","selector","contextid","formdata","init","prototype","modal","on","e","preventDefault","get_string","then","title","create","body","this","getBody","large","removeOnClose","bind","getRoot","save","submitForm","submitFormAjax","show","params","jsonformdata","JSON","stringify","loadFragment","handleFormSubmissionResponse","hide","use","M","core_formchangechecker","reset_form_dirty_state","document","location","reload","handleFormSubmissionFailure","data","setBody","formData","find","serialize","call","methodname","args","done","fail","submit"],"mappings":"AAAAA,gCAAO,CAAC,SAAU,WAAY,yBAA0B,oBAAqB,gBAAiB,YAAa,aACvG,SAASC,EAAGC,IAAKC,gBAAiBC,YAAaC,SAAUC,KAAMC,OAEvDC,aAAe,SAASC,SAAUC,UAAWC,eACxCD,UAAYA,eACZE,KAAKH,SAAUE,kBAGxBH,aAAaK,UAAUC,MAAQ,KAE/BN,aAAaK,UAAUH,WAAa,EAEpCF,aAAaK,UAAUD,KAAO,SAASH,SAAUE,UAC7CV,EAAEQ,UAAUM,GAAG,QAAS,SAASC,UAC7BA,EAAEC,iBACKf,IAAIgB,WAAW,qBAAsB,aAAaC,KAAK,SAASC,cAC5DjB,gBAAgBkB,OAAO,CAC1BD,MAAOA,MACPE,KAAMC,KAAKC,QAAQb,UACnBc,OAAO,EACPC,eAAe,KAErBC,KAAKJ,OAAOJ,KAAK,SAASL,mBACnBA,MAAQA,MAIbA,MAAMc,UAAUb,GAAGX,YAAYyB,KAAMN,KAAKO,WAAWH,KAAKJ,OAE1DT,MAAMc,UAAUb,GAAG,SAAU,OAAQQ,KAAKQ,eAAeJ,KAAKJ,OAE9DT,MAAMkB,OACClB,OACTa,KAAKJ,QACTI,KAAKJ,QASXf,aAAaK,UAAUW,QAAU,SAASb,eACd,IAAbA,WACPA,SAAW,QAGXsB,OAAS,CACTC,aAAcC,KAAKC,UAAUzB,kBAE1BN,SAASgC,aAAa,YAAa,mBAAoBd,KAAKb,UAAWuB,SAOlFzB,aAAaK,UAAUyB,6BAA+B,gBAC7CxB,MAAMyB,OAGXhC,EAAEiC,IAAI,iCAAiC,WACnCC,EAAEC,uBAAuBC,4BAG7BC,SAASC,SAASC,UAQtBtC,aAAaK,UAAUkC,4BAA8B,SAASC,WAGrDlC,MAAMmC,QAAQ1B,KAAKC,QAAQwB,QAUpCxC,aAAaK,UAAUkB,eAAiB,SAASf,GAE7CA,EAAEC,qBAGEiC,SAAW3B,KAAKT,MAAMc,UAAUuB,KAAK,QAAQC,YAEjD9C,KAAK+C,KAAK,CAAC,CACPC,WAAY,qCACZC,KAAM,CACF7C,UAAWa,KAAKb,UAChBwB,aAAcC,KAAKC,UAAUc,WAEjCM,KAAMjC,KAAKe,6BAA6BX,KAAKJ,KAAM2B,UACnDO,KAAMlC,KAAKwB,4BAA4BpB,KAAKJ,KAAM2B,cAW1D1C,aAAaK,UAAUiB,WAAa,SAASd,GACzCA,EAAEC,sBACGH,MAAMc,UAAUuB,KAAK,QAAQO,UAGW,CAW7C9C,KAAM,SAASH,SAAUC,UAAWC,iBACzB,IAAIH,aAAaC,SAAUC,UAAWC"} \ No newline at end of file +{"version":3,"file":"duedate_form.min.js","sources":["../src/duedate_form.js"],"sourcesContent":["define([\n 'jquery',\n 'core/str',\n 'core/modal_save_cancel',\n 'core/modal_events',\n 'core/fragment',\n 'core/ajax',\n 'core_form/changechecker',\n], function($, Str, ModalSaveCancel, ModalEvents, Fragment, Ajax, FormChangeChecker) {\n\n var MumieDueDate = function(selector, contextid, formdata) {\n this.contextid = contextid;\n this.init(selector, formdata);\n };\n\n MumieDueDate.prototype.modal = null;\n\n MumieDueDate.prototype.contextid = -1;\n\n MumieDueDate.prototype.init = function(selector, formdata) {\n $(selector).on('click', function(e) {\n e.preventDefault();\n return Str.get_string('mumie_duedate_form', 'mod_mumie').then(function(title) {\n return ModalSaveCancel.create({\n title: title,\n body: this.getBody(formdata),\n large: true,\n removeOnClose: true,\n });\n }.bind(this)).then(function(modal) {\n this.modal = modal;\n\n // We catch the modal save event, and use it to submit the form inside the modal.\n // Triggering a form submission will give JS validation scripts a chance to check for errors.\n modal.getRoot().on(ModalEvents.save, this.submitForm.bind(this));\n // We also catch the form submit event and use it to submit the form with ajax.\n modal.getRoot().on('submit', 'form', this.submitFormAjax.bind(this));\n\n modal.show();\n return modal;\n }.bind(this));\n }.bind(this));\n };\n\n /**\n * @method getBody\n * @private\n * @param {Object} formdata\n * @return {Promise}\n */\n MumieDueDate.prototype.getBody = function(formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n // Get the content of the modal.\n var params = {\n jsonformdata: JSON.stringify(formdata)\n };\n return Fragment.loadFragment('mod_mumie', 'new_duedate_form', this.contextid, params);\n };\n\n /**\n * @method handleFormSubmissionResponse\n * @private\n */\n MumieDueDate.prototype.handleFormSubmissionResponse = function() {\n this.modal.hide();\n FormChangeChecker.resetAllFormDirtyStates();\n document.location.reload();\n };\n\n /**\n * @method handleFormSubmissionFailure\n * @private\n * @param {Object} data\n */\n MumieDueDate.prototype.handleFormSubmissionFailure = function(data) {\n // Oh noes! Epic fail :(\n // Ah wait - this is normal. We need to re-display the form with errors!\n this.modal.setBody(this.getBody(data));\n };\n\n /**\n * Private method\n *\n * @method submitFormAjax\n * @private\n * @param {Event} e Form submission event.\n */\n MumieDueDate.prototype.submitFormAjax = function(e) {\n // We don't want to do a real form submission.\n e.preventDefault();\n\n // Convert all the form elements values to a serialized string.\n var formData = this.modal.getRoot().find('form').serialize();\n // Now we can continue...\n Ajax.call([{\n methodname: 'mod_mumie_submit_mumieduedate_form',\n args: {\n contextid: this.contextid,\n jsonformdata: JSON.stringify(formData)\n },\n done: this.handleFormSubmissionResponse.bind(this, formData),\n fail: this.handleFormSubmissionFailure.bind(this, formData)\n }]);\n };\n\n /**\n * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.\n *\n * @method submitForm\n * @param {Event} e Form submission event.\n * @private\n */\n MumieDueDate.prototype.submitForm = function(e) {\n e.preventDefault();\n this.modal.getRoot().find('form').submit();\n };\n\n return /** @alias module:mod_mumie/newduedate */ {\n // Public variables and functions.\n /**\n * Attach event listeners to initialize this module.\n *\n * @method init\n * @param {string} selector The CSS selector used to find nodes that will trigger this module.\n * @param {int} contextid The contextid for the course.\n * @param {Object} formdata\n * @return {Promise}\n */\n init: function(selector, contextid, formdata) {\n return new MumieDueDate(selector, contextid, formdata);\n }\n };\n\n });"],"names":["define","$","Str","ModalSaveCancel","ModalEvents","Fragment","Ajax","FormChangeChecker","MumieDueDate","selector","contextid","formdata","init","prototype","modal","on","e","preventDefault","get_string","then","title","create","body","this","getBody","large","removeOnClose","bind","getRoot","save","submitForm","submitFormAjax","show","params","jsonformdata","JSON","stringify","loadFragment","handleFormSubmissionResponse","hide","resetAllFormDirtyStates","document","location","reload","handleFormSubmissionFailure","data","setBody","formData","find","serialize","call","methodname","args","done","fail","submit"],"mappings":"AAAAA,gCAAO,CACH,SACA,WACA,yBACA,oBACA,gBACA,YACA,4BACD,SAASC,EAAGC,IAAKC,gBAAiBC,YAAaC,SAAUC,KAAMC,uBAEtDC,aAAe,SAASC,SAAUC,UAAWC,eACxCD,UAAYA,eACZE,KAAKH,SAAUE,kBAGxBH,aAAaK,UAAUC,MAAQ,KAE/BN,aAAaK,UAAUH,WAAa,EAEpCF,aAAaK,UAAUD,KAAO,SAASH,SAAUE,UAC7CV,EAAEQ,UAAUM,GAAG,QAAS,SAASC,UAC7BA,EAAEC,iBACKf,IAAIgB,WAAW,qBAAsB,aAAaC,KAAK,SAASC,cAC5DjB,gBAAgBkB,OAAO,CAC1BD,MAAOA,MACPE,KAAMC,KAAKC,QAAQb,UACnBc,OAAO,EACPC,eAAe,KAErBC,KAAKJ,OAAOJ,KAAK,SAASL,mBACnBA,MAAQA,MAIbA,MAAMc,UAAUb,GAAGX,YAAYyB,KAAMN,KAAKO,WAAWH,KAAKJ,OAE1DT,MAAMc,UAAUb,GAAG,SAAU,OAAQQ,KAAKQ,eAAeJ,KAAKJ,OAE9DT,MAAMkB,OACClB,OACTa,KAAKJ,QACTI,KAAKJ,QASXf,aAAaK,UAAUW,QAAU,SAASb,eACd,IAAbA,WACPA,SAAW,QAGXsB,OAAS,CACTC,aAAcC,KAAKC,UAAUzB,kBAE1BN,SAASgC,aAAa,YAAa,mBAAoBd,KAAKb,UAAWuB,SAOlFzB,aAAaK,UAAUyB,6BAA+B,gBAC7CxB,MAAMyB,OACXhC,kBAAkBiC,0BAClBC,SAASC,SAASC,UAQtBnC,aAAaK,UAAU+B,4BAA8B,SAASC,WAGrD/B,MAAMgC,QAAQvB,KAAKC,QAAQqB,QAUpCrC,aAAaK,UAAUkB,eAAiB,SAASf,GAE7CA,EAAEC,qBAGE8B,SAAWxB,KAAKT,MAAMc,UAAUoB,KAAK,QAAQC,YAEjD3C,KAAK4C,KAAK,CAAC,CACPC,WAAY,qCACZC,KAAM,CACF1C,UAAWa,KAAKb,UAChBwB,aAAcC,KAAKC,UAAUW,WAEjCM,KAAM9B,KAAKe,6BAA6BX,KAAKJ,KAAMwB,UACnDO,KAAM/B,KAAKqB,4BAA4BjB,KAAKJ,KAAMwB,cAW1DvC,aAAaK,UAAUiB,WAAa,SAASd,GACzCA,EAAEC,sBACGH,MAAMc,UAAUoB,KAAK,QAAQO,UAGW,CAW7C3C,KAAM,SAASH,SAAUC,UAAWC,iBACzB,IAAIH,aAAaC,SAAUC,UAAWC"} \ No newline at end of file diff --git a/amd/src/duedate_form.js b/amd/src/duedate_form.js index 118f2929..09e4ff49 100644 --- a/amd/src/duedate_form.js +++ b/amd/src/duedate_form.js @@ -1,5 +1,12 @@ -define(['jquery', 'core/str', 'core/modal_save_cancel', 'core/modal_events', 'core/fragment', 'core/ajax', 'core/yui'], - function($, Str, ModalSaveCancel, ModalEvents, Fragment, Ajax, Y) { +define([ + 'jquery', + 'core/str', + 'core/modal_save_cancel', + 'core/modal_events', + 'core/fragment', + 'core/ajax', + 'core_form/changechecker', +], function($, Str, ModalSaveCancel, ModalEvents, Fragment, Ajax, FormChangeChecker) { var MumieDueDate = function(selector, contextid, formdata) { this.contextid = contextid; @@ -58,12 +65,7 @@ define(['jquery', 'core/str', 'core/modal_save_cancel', 'core/modal_events', 'co */ MumieDueDate.prototype.handleFormSubmissionResponse = function() { this.modal.hide(); - // We could trigger an event instead. - // Yuk. - Y.use('moodle-core-formchangechecker', function() { - M.core_formchangechecker.reset_form_dirty_state(); - }); - + FormChangeChecker.resetAllFormDirtyStates(); document.location.reload(); }; From 45b73c056f627788031cba297f621fcca2608369 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Fri, 19 Jun 2026 03:19:00 +0200 Subject: [PATCH 063/101] fix delete duedate error --- delete_duedate_extension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delete_duedate_extension.php b/delete_duedate_extension.php index a01497fa..560cb3e3 100644 --- a/delete_duedate_extension.php +++ b/delete_duedate_extension.php @@ -33,7 +33,7 @@ $cmid = required_param('cmid', PARAM_INT); $returnurl = new \moodle_url('/mod/mumie/view.php', ["id" => $cmid, "action" => "grading"]); -require_capability('mod/mumie:revokeduedateextension', context_system::instance()); +require_capability('mod/mumie:revokeduedateextension', \core\context\system::instance()); $extension = mod_mumie\mumie_duedate_extension::load_by_id($duedateid); $extension->delete(); $calendarservice = new mod_mumie\mumie_individual_calendar_service($extension->get_mumie(), $extension->get_userid()); From d2b26204b3636a9a2bcfb5946cfa93a38434a896 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Fri, 19 Jun 2026 03:25:25 +0200 Subject: [PATCH 064/101] fix delete duedate error --- delete_duedate_extension.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/delete_duedate_extension.php b/delete_duedate_extension.php index 560cb3e3..9906aa42 100644 --- a/delete_duedate_extension.php +++ b/delete_duedate_extension.php @@ -34,9 +34,9 @@ $returnurl = new \moodle_url('/mod/mumie/view.php', ["id" => $cmid, "action" => "grading"]); require_capability('mod/mumie:revokeduedateextension', \core\context\system::instance()); -$extension = mod_mumie\mumie_duedate_extension::load_by_id($duedateid); +$extension = mumie_duedate_extension::load_by_id($duedateid); $extension->delete(); -$calendarservice = new mod_mumie\mumie_individual_calendar_service($extension->get_mumie(), $extension->get_userid()); +$calendarservice = new mumie_individual_calendar_service($extension->get_mumie(), $extension->get_userid()); $calendarservice->update(); redirect($returnurl); From f7ecd92106a15049d154c2c9974242e64519a8bc Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Fri, 19 Jun 2026 03:39:23 +0200 Subject: [PATCH 065/101] require moodle 4.3+ --- version.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.php b/version.php index d7e9063f..1bc508ff 100644 --- a/version.php +++ b/version.php @@ -27,7 +27,7 @@ $plugin->version = 2025070300; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). -$plugin->requires = 2022112800; // 4.1 LTS +$plugin->requires = 2023100900; // 4.3 $plugin->release = "v1.9.1"; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = [ From 16c61a3667196eb8e2c34736690132e3e1d747b7 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 19 Jun 2026 13:59:37 +0200 Subject: [PATCH 066/101] Fix lang key ordering, remove misplaced multiTaskEditController.init() call and improve task selection label --- amd/src/mod_form.js | 1 - lang/de/mumie.php | 6 +++--- lang/en/mumie.php | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 3651a241..c4f55c37 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -783,7 +783,6 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv problemSelectorController.init(); durationController.init(); } - multiTaskEditController.init(); if (addServerButton) { require(['auth_mumie/mumie_server_config'], function(MumieServer) { MumieServer.init(addServerButton, contextId); diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 58dbc821..4d9dd896 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -95,6 +95,7 @@ $string['mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'] = "Das ausgewählte Worksheet darf keinen begrenzten Bearbeitungszeitraum haben.

Wählen Sie ein Worksheet mit entsprechender Konfiguration aus, wenn Sie eine Frist setzen möchten."; $string['mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, die bereits den Bearbeitungszeitraum Typ \'Abgabefrist\' haben.'; $string['mumie_form_deadline_required_for_trigger_after_deadline'] = "Das ausgewählte Worksheet setzt einen festgelegten Bearbeitungszeitraum voraus"; +$string['mumie_form_due_date_multi_edit_hint'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, welche vorher bereits mit dem Bearbeitungszeitraum Typ \'Abgabefrist\' erstellt wurden.'; $string['mumie_form_due_date_must_be_future'] = 'Das Datum der Abgabefrist kann nicht in der Vergangenheit liegen!'; $string['mumie_form_filter'] = 'MUMIE-Tasks filtern'; $string['mumie_form_grade_pool'] = 'Punkte mit anderen Kursen teilen'; @@ -117,12 +118,11 @@ $string['mumie_form_task_properties_selection_info'] = 'Wählen Sie die Eigenschaften dieser MUMIE-Task aus, die in anderen MUMIE-Tasks übernommen werden sollen.'; $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'; -$string['mumie_form_due_date_multi_edit_hint'] = 'Abgabefrist kann nur für MUMIE-Tasks übernommen werden, welche vorher bereits mit dem Bearbeitungszeitraum Typ \'Abgabefrist\' erstellt wurden.'; $string['mumie_form_tasks_selection_info'] = 'Bestimmen Sie die MUMIE-Tasks, für die die ausgewählten Eigenschaften ebenfalls übernommen werden sollen.'; $string['mumie_form_topic'] = 'Thema: {$a}'; -$string['mumie_form_working_period_not_duedate_warning'] = 'Bearbeitungszeitraum: keine Abgabefrist'; $string['mumie_form_updated_selection'] = 'Aufgabe erfolgreich ausgewählt'; $string['mumie_form_wiki_link'] = 'Bitte besuchen Sie unser Wiki für weiterführende Informationen!'; +$string['mumie_form_working_period_not_duedate_warning'] = 'Bearbeitungszeitraum: keine Abgabefrist'; $string['mumie_general_duedate'] = 'Allgemeine Abgabefrist:'; $string['mumie_general_timelimit'] = 'Zeitlimit: '; $string['mumie_grade_invalid'] = 'Bewertung ungültig!'; @@ -130,7 +130,7 @@ $string['mumie_grade_percentage'] = 'Bewerung in %'; $string['mumie_grading_settings'] = "Individuelle Bewertungseinstellungen"; $string['mumie_multi_problem_selector'] = 'Alternativ können Sie mit der Mehrfach-Aufgabenauswahl auch mehrere MUMIE-Aufgaben auf einmal auswählen. Alle Aufgaben werden mit den eingestellten Einstellungen angelegt (Punkte, Frist, Startcontainer etc.). Jede Aufgabe behält ihren eigenen Namen — anders als bei der Einzelauswahl kann kein eigener Name vergeben werden.

Weitere Informationen finden Sie in unserem Wiki'; -$string['mumie_multi_tasks_selected'] = '{$a} Tasks ausgewählt:'; +$string['mumie_multi_tasks_selected'] = 'Sie haben folgende {$a} Aufgaben ausgewählt:'; $string['mumie_no_other_task_found'] = 'Keine andere MUMIE Tasks in Kurs gefunden'; $string['mumie_no_submissions'] = 'Keine Antworten abgegeben'; $string['mumie_open_task'] = 'MUMIE-Task öffnen'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index d9c991a2..93713839 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -84,6 +84,7 @@ $string['mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'] = "The selected worksheet cannot have a limited working period.

If you want to limit the working period, please select a worksheet with an appropriate configuration."; $string['mumie_form_deadline_transfer_prohibited_for_tasks_without_deadline'] = 'Deadline can only be applied to tasks that already have the working period type \'Deadline\' set.'; $string['mumie_form_deadline_required_for_trigger_after_deadline'] = "The selected worksheet requires a limited working period."; +$string['mumie_form_due_date_multi_edit_hint'] = 'Deadline can only be applied to tasks that were previously created with the working period type \'Deadline\'.'; $string['mumie_form_due_date_must_be_future'] = 'You must select a date in the future!'; $string['mumie_form_filter'] = 'Filter MUMIE problems'; $string['mumie_form_grade_pool'] = 'Share grades with other courses'; @@ -111,13 +112,12 @@ $string['mumie_form_task_properties_selection_info'] = 'Select the properties of the current MUMIE Task to apply to other MUMIE Tasks.'; $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.'; -$string['mumie_form_due_date_multi_edit_hint'] = 'Deadline can only be applied to tasks that were previously created with the working period type \'Deadline\'.'; $string['mumie_form_tasks_selection_info'] = 'Choose the MUMIE Tasks you want to apply the selected changes to.'; $string['mumie_form_title'] = 'Configure MUMIE Server'; $string['mumie_form_topic'] = 'Topic: {$a}'; -$string['mumie_form_working_period_not_duedate_warning'] = 'Working period: not Deadline'; $string['mumie_form_updated_selection'] = 'Successfully selected problem'; $string['mumie_form_wiki_link'] = 'For help and advanced features, please visit our Wiki!'; +$string['mumie_form_working_period_not_duedate_warning'] = 'Working period: not Deadline'; $string['mumie_general_duedate'] = 'General due date:'; $string['mumie_general_timelimit'] = 'Timelimit: '; $string['mumie_grade_invalid'] = 'Grade is invalid!'; @@ -125,7 +125,7 @@ $string['mumie_grade_percentage'] = 'Grade in %'; $string['mumie_grading_settings'] = "Individual grading settings"; $string['mumie_multi_problem_selector'] = 'Alternatively, you can also create multiple MUMIE Tasks at once using the Multi Problem Selector. All tasks will be created with the settings configured (points, deadline, container type, etc.). Each task keeps its own name — unlike single task creation, no custom name can be assigned.

For more information, have a look at our wiki'; -$string['mumie_multi_tasks_selected'] = '{$a} tasks selected:'; +$string['mumie_multi_tasks_selected'] = 'You have selected the following {$a} problems:'; $string['mumie_no_other_task_found'] = 'No other MUMIE Tasks found in course'; $string['mumie_no_submissions'] = 'No answers submitted'; $string['mumie_open_task'] = 'Open MUMIE Task'; From 77b0cf6640509e9dfd1b1f2c9311045196273780 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 19 Jun 2026 14:43:08 +0200 Subject: [PATCH 067/101] Rebuild AMD build files Co-Authored-By: Claude Sonnet 4.6 --- 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 3a69ca48..aef49c8e 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),multiTaskEditController.init(),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 774e564a..8b8507ae 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.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 const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasksField","summary","innerHTML","nameField","nameFieldContainer","querySelectorAll","forEach","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","tasks","taskListItems","map","task","taskListItem","createElement","textContent","taskCountLabel","taskList","Str","get_string","length","then","label","margin","appendChild","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","errorMessage","durationSelectorField","workingPeriodContainer","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasksField","summary","innerHTML","nameField","nameFieldContainer","querySelectorAll","forEach","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","tasks","taskListItems","map","task","taskListItem","createElement","textContent","taskCountLabel","taskList","Str","get_string","length","then","label","margin","appendChild","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","errorMessage","durationSelectorField","workingPeriodContainer","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"mappings":"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"} \ No newline at end of file From c95081dd0c4a7d5dc9b361bf3e693025749fc2bc Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Mon, 22 Jun 2026 13:23:07 +0200 Subject: [PATCH 068/101] wip reuse single problem select --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 156 ++++++++++++++-------------------- externallib.php | 132 ++++++++++------------------ forms/form_field_decoder.php | 109 ++++++++++++++++++++++++ lang/de/mumie.php | 1 + lang/en/mumie.php | 1 + mod_form.php | 2 +- 8 files changed, 225 insertions(+), 180 deletions(-) create mode 100644 forms/form_field_decoder.php diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index aef49c8e..2cc7a806 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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=>{var _importObj$worksheet;if(event.origin!==lmsSelectorUrl)return;const importObj=JSON.parse(event.data);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();const isGraded=!1!==importObj.isGraded,worksheet=null!==(_importObj$worksheet=importObj.worksheet)&&void 0!==_importObj$worksheet?_importObj$worksheet:null;try{courseController.setCourse(importObj.path_to_coursefile),langController.setLanguage(importObj.language),taskController.setSelection(importObj.link,importObj.language,importObj.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:function(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")},hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements,_document$getElementB2;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,deadlineValidationError=function(tasks){var _document$getElementB;const durationSelector=(null===(_document$getElementB=document.getElementById("id_duration_selector"))||void 0===_document$getElementB?void 0:_document$getElementB.value)||"unlimited",hasDeadline="duedate"===durationSelector||"timelimit"===durationSelector;for(const task of tasks){var _worksheetConfig$conf,_worksheetConfig$conf2;if(!task.worksheet)continue;const worksheetConfig=task.worksheet,triggerAfterDeadline="AFTER_DEADLINE"===(null==worksheetConfig||null===(_worksheetConfig$conf=worksheetConfig.configuration)||void 0===_worksheetConfig$conf||null===(_worksheetConfig$conf2=_worksheetConfig$conf.correction)||void 0===_worksheetConfig$conf2?void 0:_worksheetConfig$conf2.correctorType);if(triggerAfterDeadline&&!hasDeadline)return"mumie_form_deadline_required_for_trigger_after_deadline";if(!triggerAfterDeadline&&hasDeadline)return"mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline"}return null}(JSON.parse(tasksField.value));if(deadlineValidationError)return void require(["core/str"],(function(Str){Str.get_string(deadlineValidationError,"mod_mumie").then((function(errorMessage){const durationSelectorField=document.getElementById("id_duration_selector"),workingPeriodContainer=durationSelectorField&&durationSelectorField.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.add("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.innerHTML=errorMessage,feedback.style.display="block");const collapsibleSection=workingPeriodContainer.closest(".collapse:not(.show)");if(collapsibleSection){collapsibleSection.classList.add("show");const sectionToggleButton=document.querySelector('[aria-controls="'+collapsibleSection.id+'"]');sectionToggleButton&§ionToggleButton.setAttribute("aria-expanded","true")}}durationSelectorField&&(durationSelectorField.scrollIntoView({behavior:"smooth",block:"center"}),durationSelectorField.focus())}))}));const workingPeriodContainer=null===(_document$getElementB2=document.getElementById("id_duration_selector"))||void 0===_document$getElementB2?void 0:_document$getElementB2.closest(".fitem");if(workingPeriodContainer){workingPeriodContainer.classList.remove("has-danger");const feedback=workingPeriodContainer.querySelector(".form-control-feedback");feedback&&(feedback.style.display="none")}const settings=function(){const section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),sensitiveFields=["sesskey","_qf__mod_mumie_mod_form"],formData=form?Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!sensitiveFields.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&"):"";return{contextid:parseInt(contextId),section:section,formdata:formData}}();settings.tasks=tasksField.value,require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:settings}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 8b8507ae..1b8e8f84 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n const isGraded = importObj.isGraded !== false;\n const worksheet = importObj.worksheet ?? null;\n try {\n courseController.setCourse(importObj.path_to_coursefile);\n langController.setLanguage(importObj.language);\n taskController.setSelection(importObj.link, importObj.language, importObj.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Collect current form settings for multi-task creation.\n * @returns {Object} form settings\n */\n function collectFormSettings() {\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form'];\n const formData = form\n ? Array.from(new FormData(form))\n .filter(([key]) => !sensitiveFields.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n : '';\n return {\n contextid: parseInt(contextId),\n section: section,\n formdata: formData,\n };\n }\n\n /**\n * Validate worksheet deadline requirements against current duration_selector.\n * Returns a lang string key if invalid, null if valid.\n * @param {Array} tasks\n * @returns {string|null}\n */\n function validateWorksheetDeadlines(tasks) {\n const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited';\n const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit';\n for (const task of tasks) {\n if (!task.worksheet) {\n continue;\n }\n const worksheetConfig = task.worksheet;\n const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE';\n if (triggerAfterDeadline && !hasDeadline) {\n return 'mumie_form_deadline_required_for_trigger_after_deadline';\n }\n if (!triggerAfterDeadline && hasDeadline) {\n return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline';\n }\n }\n return null;\n }\n\n /**\n * Submit multi-tasks via AJAX using current form settings, then redirect to course.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const tasks = JSON.parse(tasksField.value);\n const deadlineValidationError = validateWorksheetDeadlines(tasks);\n if (deadlineValidationError) {\n require(['core/str'], function(Str) {\n Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) {\n const durationSelectorField = document.getElementById('id_duration_selector');\n const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.add('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.innerHTML = errorMessage;\n feedback.style.display = 'block';\n }\n const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)');\n if (collapsibleSection) {\n collapsibleSection.classList.add('show');\n const sectionToggleButton = document.querySelector(\n '[aria-controls=\"' + collapsibleSection.id + '\"]'\n );\n if (sectionToggleButton) {\n sectionToggleButton.setAttribute('aria-expanded', 'true');\n }\n }\n }\n if (durationSelectorField) {\n durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'});\n durationSelectorField.focus();\n }\n });\n });\n return;\n }\n const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem');\n if (workingPeriodContainer) {\n workingPeriodContainer.classList.remove('has-danger');\n const feedback = workingPeriodContainer.querySelector('.form-control-feedback');\n if (feedback) {\n feedback.style.display = 'none';\n }\n }\n const settings = collectFormSettings();\n settings.tasks = tasksField.value;\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: settings,\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","worksheet","courseController","setCourse","path_to_coursefile","langController","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasksField","summary","innerHTML","nameField","nameFieldContainer","querySelectorAll","forEach","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","tasks","taskListItems","map","task","taskListItem","createElement","textContent","taskCountLabel","taskList","Str","get_string","length","then","label","margin","appendChild","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","deadlineValidationError","hasDeadline","worksheetConfig","triggerAfterDeadline","configuration","correction","correctorType","validateWorksheetDeadlines","errorMessage","durationSelectorField","workingPeriodContainer","classList","add","feedback","collapsibleSection","sectionToggleButton","id","scrollIntoView","behavior","block","_document$getElementB2","remove","settings","section","parseInt","URLSearchParams","search","get","submitButton","form","sensitiveFields","formData","from","FormData","filter","_ref","key","_ref2","join","contextid","formdata","collectFormSettings","Ajax","Notification","call","methodname","args","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface via Notification.exception.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","langController","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 c4f55c37..fcc93e6c 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -170,14 +170,8 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv return; } - const isGraded = importObj.isGraded !== false; - const worksheet = importObj.worksheet ?? null; try { - courseController.setCourse(importObj.path_to_coursefile); - langController.setLanguage(importObj.language); - taskController.setSelection(importObj.link, importObj.language, importObj.name); - taskController.setIsGraded(isGraded); - worksheetController.setWorksheet(worksheet); + applyPickerPayloadToForm(importObj); sendSuccess(); window.focus(); displayProblemSelectedMessage(); @@ -303,6 +297,25 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }; })(); + /** + * Apply a picker payload to the form's per-task fields. + * + * Single source of truth for picker-payload → form-field mapping. + * Used by both the single-task postMessage handler and the multi-task + * submit loop, so new picker fields only need to be wired here. + * + * @param {Object} payload picker payload for one task + */ + function applyPickerPayloadToForm(payload) { + const isGraded = payload.isGraded !== false; + const worksheet = payload.worksheet ?? null; + courseController.setCourse(payload.path_to_coursefile); + langController.setLanguage(payload.language); + taskController.setSelection(payload.link, payload.language, payload.name); + taskController.setIsGraded(isGraded); + worksheetController.setWorksheet(worksheet); + } + const courseController = (function() { const courseNameElem = document.getElementById("id_mumie_course"); const courseFileElem = document.getElementsByName("mumie_coursefile")[0]; @@ -468,106 +481,65 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv } /** - * Collect current form settings for multi-task creation. - * @returns {Object} form settings + * Serialize a form into a URL-encoded POST string, omitting form mechanics + * the webservice does not need (sesskey, qf form marker). + * + * Disabled form controls are temporarily enabled so FormData includes them: + * the picker writes values to display-only inputs (e.g. mumie_course) that + * the server-side validator still expects to receive. + * + * @param {HTMLFormElement} form + * @returns {string} */ - function collectFormSettings() { - const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0); - const submitButton = document.getElementById('id_submitbutton'); - const form = submitButton && submitButton.closest('form'); - const sensitiveFields = ['sesskey', '_qf__mod_mumie_mod_form']; - const formData = form - ? Array.from(new FormData(form)) - .filter(([key]) => !sensitiveFields.includes(key)) + function serializeFormFields(form) { + const disabledFields = Array.from(form.querySelectorAll(':disabled')); + disabledFields.forEach(field => { field.disabled = false; }); + try { + const omit = ['sesskey', '_qf__mod_mumie_mod_form']; + return Array.from(new FormData(form)) + .filter(([key]) => !omit.includes(key)) .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value)) - .join('&') - : ''; - return { - contextid: parseInt(contextId), - section: section, - formdata: formData, - }; - } - - /** - * Validate worksheet deadline requirements against current duration_selector. - * Returns a lang string key if invalid, null if valid. - * @param {Array} tasks - * @returns {string|null} - */ - function validateWorksheetDeadlines(tasks) { - const durationSelector = document.getElementById('id_duration_selector')?.value || 'unlimited'; - const hasDeadline = durationSelector === 'duedate' || durationSelector === 'timelimit'; - for (const task of tasks) { - if (!task.worksheet) { - continue; - } - const worksheetConfig = task.worksheet; - const triggerAfterDeadline = worksheetConfig?.configuration?.correction?.correctorType === 'AFTER_DEADLINE'; - if (triggerAfterDeadline && !hasDeadline) { - return 'mumie_form_deadline_required_for_trigger_after_deadline'; - } - if (!triggerAfterDeadline && hasDeadline) { - return 'mumie_form_deadline_prohibited_for_worksheet_without_trigger_after_deadline'; - } + .join('&'); + } finally { + disabledFields.forEach(field => { field.disabled = true; }); } - return null; } /** - * Submit multi-tasks via AJAX using current form settings, then redirect to course. + * Submit multi-tasks via AJAX, then redirect to course. + * + * Builds one full form payload per task by applying each picker payload + * to the live form and serializing it. The server treats each entry as + * an independent single-task submission, so picker-payload → form-field + * mapping lives in applyPickerPayloadToForm and is shared with the + * single-task path. Validation runs server-side via the shared form + * pipeline; errors surface via Notification.exception. */ function submitMultiTasks() { const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; const courseId = document.getElementsByName('course')[0]?.value; + const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0); + const submitButton = document.getElementById('id_submitbutton'); + const form = submitButton && submitButton.closest('form'); const tasks = JSON.parse(tasksField.value); - const deadlineValidationError = validateWorksheetDeadlines(tasks); - if (deadlineValidationError) { - require(['core/str'], function(Str) { - Str.get_string(deadlineValidationError, 'mod_mumie').then(function(errorMessage) { - const durationSelectorField = document.getElementById('id_duration_selector'); - const workingPeriodContainer = durationSelectorField && durationSelectorField.closest('.fitem'); - if (workingPeriodContainer) { - workingPeriodContainer.classList.add('has-danger'); - const feedback = workingPeriodContainer.querySelector('.form-control-feedback'); - if (feedback) { - feedback.innerHTML = errorMessage; - feedback.style.display = 'block'; - } - const collapsibleSection = workingPeriodContainer.closest('.collapse:not(.show)'); - if (collapsibleSection) { - collapsibleSection.classList.add('show'); - const sectionToggleButton = document.querySelector( - '[aria-controls="' + collapsibleSection.id + '"]' - ); - if (sectionToggleButton) { - sectionToggleButton.setAttribute('aria-expanded', 'true'); - } - } - } - if (durationSelectorField) { - durationSelectorField.scrollIntoView({behavior: 'smooth', block: 'center'}); - durationSelectorField.focus(); - } - }); - }); - return; - } - const workingPeriodContainer = document.getElementById('id_duration_selector')?.closest('.fitem'); - if (workingPeriodContainer) { - workingPeriodContainer.classList.remove('has-danger'); - const feedback = workingPeriodContainer.querySelector('.form-control-feedback'); - if (feedback) { - feedback.style.display = 'none'; - } - } - const settings = collectFormSettings(); - settings.tasks = tasksField.value; + + const tasksFormData = tasks.map(task => { + applyPickerPayloadToForm(task); + return serializeFormFields(form); + }); + + // applyPickerPayloadToForm leaves the form in single-task mode of the last task; + // restore the multi-task UI so the form is coherent if the AJAX call fails. + setMultiSelection(tasks); require(['core/ajax', 'core/notification'], function(Ajax, Notification) { Ajax.call([{ methodname: 'mod_mumie_create_multiple_tasks', - args: settings, + args: { + contextid: parseInt(contextId), + section: section, + tasksformdata: tasksFormData, + }, }])[0].done(function() { window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; }).fail(Notification.exception); diff --git a/externallib.php b/externallib.php index dd8d8657..9c4177dc 100644 --- a/externallib.php +++ b/externallib.php @@ -132,37 +132,44 @@ public static function submit_mumieduedate_form_returns() { */ public static function create_multiple_tasks_parameters() { return new external_function_parameters([ - 'contextid' => new external_value(PARAM_INT, 'Context id of the course'), - 'section' => new external_value(PARAM_INT, 'Section number to add tasks to'), - 'tasks' => new external_value(PARAM_RAW, 'JSON array of task objects'), - 'formdata' => new external_value(PARAM_RAW, 'URL-encoded form data for settings'), + 'contextid' => new external_value(PARAM_INT, 'Context id of the course'), + 'section' => new external_value(PARAM_INT, 'Section number to add tasks to'), + 'tasksformdata' => new external_multiple_structure( + new external_value(PARAM_RAW, 'URL-encoded form POST for one task'), + 'One serialized form POST per task to create' + ), ]); } /** - * Create multiple MUMIE tasks at once with shared settings. + * Create multiple MUMIE tasks at once. + * + * Each entry of tasksformdata is the same payload the form would submit + * for a single task. The picker-payload → form-field mapping lives in JS + * (applyPickerPayloadToForm) and is shared with the single-task path, so + * adding a new picker field doesn't require parallel PHP changes. * * @param int $contextid Course context id * @param int $section Section number - * @param string $tasks JSON array of task objects - * @param string $formdata URL-encoded serialized form data + * @param string[] $tasksformdata One URL-encoded form POST per task * @return array Array of created course module ids */ - public static function create_multiple_tasks($contextid, $section, $tasks, $formdata) { + public static function create_multiple_tasks($contextid, $section, $tasksformdata) { global $CFG, $DB; require_once($CFG->dirroot . '/course/modlib.php'); require_once($CFG->dirroot . '/mod/mumie/lib.php'); require_once($CFG->dirroot . '/mod/mumie/locallib.php'); - require_once($CFG->dirroot . '/auth/mumie/classes/mumie_server.php'); + require_once($CFG->dirroot . '/mod/mumie/mod_form.php'); + require_once($CFG->dirroot . '/mod/mumie/forms/form_field_decoder.php'); + require_once($CFG->dirroot . '/mod/mumie/forms/mumie_task_validator.php'); $params = self::validate_parameters( self::create_multiple_tasks_parameters(), [ - 'contextid' => $contextid, - 'section' => $section, - 'tasks' => $tasks, - 'formdata' => $formdata, + 'contextid' => $contextid, + 'section' => $section, + 'tasksformdata' => $tasksformdata, ] ); @@ -170,87 +177,42 @@ public static function create_multiple_tasks($contextid, $section, $tasks, $form self::validate_context($context); require_capability('mod/mumie:addinstance', $context); - $course = $DB->get_record('course', ['id' => $context->instanceid], '*', MUST_EXIST); - $mumiemodule = $DB->get_record('modules', ['name' => 'mumie'], '*', MUST_EXIST); - $taskarray = json_decode($params['tasks'], true); - if (!is_array($taskarray) || empty($taskarray)) { - throw new invalid_parameter_exception('tasks must be a non-empty JSON array'); + if (empty($params['tasksformdata'])) { + throw new invalid_parameter_exception('tasksformdata must be a non-empty array'); } - if (count($taskarray) > 50) { + if (count($params['tasksformdata']) > 50) { throw new invalid_parameter_exception('Cannot create more than 50 tasks at once'); } - $formfields = []; - parse_str($params['formdata'], $formfields); - - $points = (int)($formfields['points'] ?? 100); - $gradepass = (float)($formfields['gradepass'] ?? 0); - $gradecat = (int)($formfields['gradecat'] ?? 0); - $launchcontainer = (int)($formfields['launchcontainer'] ?? 0); - $privategradepool = (int)(isset($formfields['privategradepool']) ? $formfields['privategradepool'] : 0); - $completionpass = (int)(isset($formfields['completionpass']) ? $formfields['completionpass'] : 0); - $completionview = (int)($formfields['completionview'] ?? 0); - $durationselector = $formfields['duration_selector'] ?? 'unlimited'; - - $duedate = 0; - if ($durationselector === 'duedate' && !empty($formfields['duedate']['year'])) { - $duedate = make_timestamp( - $formfields['duedate']['year'], - $formfields['duedate']['month'], - $formfields['duedate']['day'], - $formfields['duedate']['hour'] ?? 0, - $formfields['duedate']['minute'] ?? 0 - ); - } - - $timelimit = 0; - if ($durationselector === 'timelimit' && !empty($formfields['timelimit']['timeunit'])) { - $timelimit = (int)$formfields['timelimit']['number'] * (int)$formfields['timelimit']['timeunit']; - } + $course = $DB->get_record('course', ['id' => $context->instanceid], '*', MUST_EXIST); + $mumiemodule = $DB->get_record('modules', ['name' => 'mumie'], '*', MUST_EXIST); $createdids = []; - foreach ($taskarray as $taskdata) { - $moduleinfo = new stdClass(); - $moduleinfo->modulename = 'mumie'; - $moduleinfo->module = $mumiemodule->id; - $moduleinfo->course = $course->id; - $moduleinfo->section = $params['section']; - $moduleinfo->visible = 1; - $moduleinfo->intro = ''; - $moduleinfo->introformat = FORMAT_HTML; - - $tasklink = clean_param($taskdata['link'] ?? '', PARAM_TEXT); - $taskserver = clean_param($taskdata['server'] ?? '', PARAM_URL); - if (empty($tasklink) || empty($taskserver)) { - throw new invalid_parameter_exception('Each task must have a valid link and server'); + foreach ($params['tasksformdata'] as $taskpost) { + $formfields = []; + parse_str($taskpost, $formfields); + + $instancedata = \mod_mumie\form_field_decoder::from_form_fields($formfields); + \mod_mumie_mod_form::clean_up_duration_values($instancedata); + + $instancedata->modulename = 'mumie'; + $instancedata->module = $mumiemodule->id; + $instancedata->course = $course->id; + $instancedata->section = $params['section']; + $instancedata->visible = 1; + $instancedata->intro = ''; + $instancedata->introformat = FORMAT_HTML; + if (isset($instancedata->points)) { + $instancedata->grade = (int)$instancedata->points; } - $serverobj = new \auth_mumie\mumie_server(); - $serverobj->set_urlprefix($taskserver); - - $moduleinfo->name = clean_param($taskdata['name'] ?? '', PARAM_TEXT); - $moduleinfo->language = clean_param($taskdata['language'] ?? '', PARAM_TEXT); - $moduleinfo->taskurl = $tasklink . '?lang=' . $moduleinfo->language; - $moduleinfo->mumie_coursefile = clean_param($taskdata['path_to_coursefile'] ?? '', PARAM_TEXT); - $moduleinfo->mumie_course = clean_param($taskdata['course'] ?? '', PARAM_TEXT); - $moduleinfo->server = $serverobj->get_urlprefix(); - - $moduleinfo->points = $points; - $moduleinfo->launchcontainer = $launchcontainer; - $moduleinfo->privategradepool = $privategradepool; - $moduleinfo->completionpass = $completionpass; - $moduleinfo->duration_selector = $durationselector; - $moduleinfo->duedate = $duedate; - $moduleinfo->timelimit = $timelimit; - $moduleinfo->isgraded = (int)($taskdata['isGraded'] ?? 1); - - $moduleinfo->grade = $points; - $moduleinfo->gradepass = $gradepass; - $moduleinfo->gradecat = $gradecat; - $moduleinfo->completionview = $completionview; + $errors = \mod_mumie\mumie_task_validator::get_errors((array)$instancedata, new stdClass()); + if (!empty($errors)) { + throw new moodle_exception('mumie_multi_task_validation_error', 'mod_mumie', '', reset($errors)); + } - $moduleinfo = add_moduleinfo($moduleinfo, $course); - $createdids[] = $moduleinfo->coursemodule; + $created = add_moduleinfo($instancedata, $course); + $createdids[] = $created->coursemodule; } return $createdids; diff --git a/forms/form_field_decoder.php b/forms/form_field_decoder.php new file mode 100644 index 00000000..93479e64 --- /dev/null +++ b/forms/form_field_decoder.php @@ -0,0 +1,109 @@ +. + +/** + * Decode raw mod_form POST fields into a flat $data object. + * + * @package mod_mumie + * @copyright 2017-2026 integral-learning GmbH (https://www.integral-learning.de/) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_mumie; + +use stdClass; + +/** + * Decode raw mod_form POST fields into a flat $data object. + * + * Mimics the per-element conversion that moodleform::get_data() does + * (date_selector → timestamp, duration → seconds), without instantiating + * the form. Used by the multi-task creation external function so it can + * share validation/postprocessing/persistence with the single-task path. + */ +class form_field_decoder { + /** + * Field names that are form mechanics and should not flow into $data. + */ + private const FORM_MECHANIC_FIELDS = [ + '_qf__mod_mumie_mod_form', + 'sesskey', + 'submitbutton', + 'cancel', + 'mumie_multi_tasks', + 'mumie_server_structure', + ]; + + /** + * Build a $data stdClass from raw form fields (post-parse_str). + * + * Scalar fields are copied as-is. The date_selector group `duedate` + * is converted to a unix timestamp and the duration group `timelimit` + * is converted to seconds. + * + * @param array $formfields Result of parse_str on the serialized form. + * @return stdClass + */ + public static function from_form_fields(array $formfields): stdClass { + $data = new stdClass(); + foreach ($formfields as $key => $value) { + if (in_array($key, self::FORM_MECHANIC_FIELDS, true)) { + continue; + } + if (is_array($value)) { + continue; + } + $data->$key = $value; + } + $data->duedate = self::decode_duedate($formfields); + $data->timelimit = self::decode_timelimit($formfields); + return $data; + } + + /** + * Convert a date_selector group `duedate[year|month|day|hour|minute]` to a unix timestamp. + * + * @param array $formfields + * @return int + */ + private static function decode_duedate(array $formfields): int { + $duedate = $formfields['duedate'] ?? null; + if (!is_array($duedate) || empty($duedate['year'])) { + return 0; + } + return make_timestamp( + $duedate['year'], + $duedate['month'], + $duedate['day'], + $duedate['hour'] ?? 0, + $duedate['minute'] ?? 0 + ); + } + + /** + * Convert a duration group `timelimit[number|timeunit]` to seconds. + * + * @param array $formfields + * @return int + */ + private static function decode_timelimit(array $formfields): int { + $timelimit = $formfields['timelimit'] ?? null; + if (!is_array($timelimit) || empty($timelimit['timeunit'])) { + return 0; + } + return (int)$timelimit['number'] * (int)$timelimit['timeunit']; + } +} diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 4d9dd896..ad62bc13 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -130,6 +130,7 @@ $string['mumie_grade_percentage'] = 'Bewerung in %'; $string['mumie_grading_settings'] = "Individuelle Bewertungseinstellungen"; $string['mumie_multi_problem_selector'] = 'Alternativ können Sie mit der Mehrfach-Aufgabenauswahl auch mehrere MUMIE-Aufgaben auf einmal auswählen. Alle Aufgaben werden mit den eingestellten Einstellungen angelegt (Punkte, Frist, Startcontainer etc.). Jede Aufgabe behält ihren eigenen Namen — anders als bei der Einzelauswahl kann kein eigener Name vergeben werden.

Weitere Informationen finden Sie in unserem Wiki'; +$string['mumie_multi_task_validation_error'] = 'Validierungsfehler: {$a}'; $string['mumie_multi_tasks_selected'] = 'Sie haben folgende {$a} Aufgaben ausgewählt:'; $string['mumie_no_other_task_found'] = 'Keine andere MUMIE Tasks in Kurs gefunden'; $string['mumie_no_submissions'] = 'Keine Antworten abgegeben'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 93713839..e38eae13 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -125,6 +125,7 @@ $string['mumie_grade_percentage'] = 'Grade in %'; $string['mumie_grading_settings'] = "Individual grading settings"; $string['mumie_multi_problem_selector'] = 'Alternatively, you can also create multiple MUMIE Tasks at once using the Multi Problem Selector. All tasks will be created with the settings configured (points, deadline, container type, etc.). Each task keeps its own name — unlike single task creation, no custom name can be assigned.

For more information, have a look at our wiki'; +$string['mumie_multi_task_validation_error'] = 'Validation error: {$a}'; $string['mumie_multi_tasks_selected'] = 'You have selected the following {$a} problems:'; $string['mumie_no_other_task_found'] = 'No other MUMIE Tasks found in course'; $string['mumie_no_submissions'] = 'No answers submitted'; diff --git a/mod_form.php b/mod_form.php index cebcbdc3..e5f72bf5 100644 --- a/mod_form.php +++ b/mod_form.php @@ -282,7 +282,7 @@ public function data_postprocessing($data): void { * * @param stdClass $data Submitted form data (mutated in place). */ - private static function clean_up_duration_values(stdClass $data): void { + public static function clean_up_duration_values(stdClass $data): void { if ($data->duration_selector !== 'duedate') { $data->duedate = 0; } From 2c2dc7130c3558ca9d1d7f91ee57290ad5675348 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Tue, 23 Jun 2026 01:33:41 +0200 Subject: [PATCH 069/101] update changelog --- changelog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/changelog.md b/changelog.md index 1a0be6f4..356c517a 100644 --- a/changelog.md +++ b/changelog.md @@ -8,9 +8,14 @@ All important changes to this plugin will be documented in this file. - Tasks without a 'Deadline' working period show a warning when deadline transfer is selected - Validation prevents transferring a deadline to tasks that were not created with working period type 'Deadline' +### Changed +- Plugin now requires Moodle 4.3 +- Support Moodle 5.2 + ### Fixed - MUMIE Task no longer shows working period descriptions for all options simultaneously - Inconsistent working period description texts corrected +- Deleting a due date extension no longer fails with a server error ## [v1.9.1] - 2025-07-03 ### Changed From 68d0c3bac0300c9f679890aea907430ed4e9dac2 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Tue, 23 Jun 2026 01:40:57 +0200 Subject: [PATCH 070/101] update checks --- .github/workflows/main.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7a97fc08..68651f63 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,14 +16,14 @@ jobs: fail-fast: false matrix: include: - - php: '7.4' - moodle-branch: 'MOODLE_401_STABLE' + - php: '8.1' + moodle-branch: 'MOODLE_403_STABLE' database: 'pgsql' - db-version: '12' - - php: '7.4' - moodle-branch: 'MOODLE_401_STABLE' + db-version: '13' + - php: '8.1' + moodle-branch: 'MOODLE_403_STABLE' database: 'mysqli' - db-version: '5.7' + db-version: '8.0' - php: '8.1' moodle-branch: 'MOODLE_404_STABLE' database: 'pgsql' @@ -56,6 +56,14 @@ jobs: moodle-branch: 'MOODLE_501_STABLE' database: 'mysqli' db-version: '8.4' + - php: '8.4' + moodle-branch: 'MOODLE_502_STABLE' + database: 'pgsql' + db-version: '16' + - php: '8.4' + moodle-branch: 'MOODLE_502_STABLE' + database: 'mysqli' + db-version: '8.4' services: postgres: From 6625b0942e6e334ec0d218f9a016fb761e87d390 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Tue, 23 Jun 2026 16:27:58 +0200 Subject: [PATCH 071/101] Fix FORM_MECHANIC_FIELDS in form_field_decoder Exclude mumie_selected_tasks, mumie_selected_task_properties, task_display_element and mumie_org to mumie_update_multiple_tasks trigger during multi-task creation. --- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 2 +- forms/form_field_decoder.php | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/amd/build/mod_form.min.js.map b/amd/build/mod_form.min.js.map index 1b8e8f84..85c0b7e7 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface via Notification.exception.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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 });"],"names":["define","addServerButton","document","getElementById","missingConfig","getElementsByName","lmsSelectorUrl","systemLanguage","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","langController","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface via Notification.exception.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","langController","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 fcc93e6c..97e8ed0c 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -802,4 +802,4 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv function serverConfigExists() { return document.getElementsByName("mumie_missing_config")[0].getAttribute("value") === ""; } - }); \ No newline at end of file + }); diff --git a/forms/form_field_decoder.php b/forms/form_field_decoder.php index 93479e64..28d5f3ad 100644 --- a/forms/form_field_decoder.php +++ b/forms/form_field_decoder.php @@ -45,6 +45,10 @@ class form_field_decoder { 'cancel', 'mumie_multi_tasks', 'mumie_server_structure', + 'mumie_selected_tasks', + 'mumie_selected_task_properties', + 'task_display_element', + 'mumie_org', ]; /** From 2b3278642792b5ab9e7ec5e3ecca82180c5172e4 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 10:18:00 +0200 Subject: [PATCH 072/101] Fix form_field_decoder: handle multiselect fields and split mechanic constants --- forms/form_field_decoder.php | 55 ++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/forms/form_field_decoder.php b/forms/form_field_decoder.php index 28d5f3ad..621b6ddf 100644 --- a/forms/form_field_decoder.php +++ b/forms/form_field_decoder.php @@ -36,7 +36,8 @@ */ class form_field_decoder { /** - * Field names that are form mechanics and should not flow into $data. + * Form-internals and form-side helper fields that are never instance data. + * Submission protocol markers, hidden JSON holders, display-only labels, config echoes. */ private const FORM_MECHANIC_FIELDS = [ '_qf__mod_mumie_mod_form', @@ -45,38 +46,74 @@ class form_field_decoder { 'cancel', 'mumie_multi_tasks', 'mumie_server_structure', - 'mumie_selected_tasks', - 'mumie_selected_task_properties', 'task_display_element', 'mumie_org', ]; + /** + * Real form fields that the multi-create flow must NOT carry into per-task $instancedata. + * + * mumie_selected_tasks / mumie_selected_task_properties drive the single-task "apply + * settings to other MUMIE tasks" sidebar. If they leak into a per-task moduleinfo, + * mumie_add_instance → mumie_update_multiple_tasks would cascade the per-task settings + * onto the listed tasks once per created instance. + */ + private const MULTI_CREATE_SUPPRESSED_FIELDS = [ + 'mumie_selected_tasks', + 'mumie_selected_task_properties', + ]; + /** * Build a $data stdClass from raw form fields (post-parse_str). * - * Scalar fields are copied as-is. The date_selector group `duedate` - * is converted to a unix timestamp and the duration group `timelimit` - * is converted to seconds. + * Scalar fields are copied as-is. The date_selector group `duedate` is converted to a + * unix timestamp and the duration group `timelimit` is converted to seconds. Other array + * fields (e.g. tags, competencies — multi-select autocompletes) are passed through, with + * the '_qf__force_multiselect_submission' sentinel normalised to an empty array, matching + * what MoodleQuickForm_autocomplete::exportValue() does for empty multi-selects. * * @param array $formfields Result of parse_str on the serialized form. * @return stdClass */ public static function from_form_fields(array $formfields): stdClass { + $excluded = array_merge(self::FORM_MECHANIC_FIELDS, self::MULTI_CREATE_SUPPRESSED_FIELDS); $data = new stdClass(); foreach ($formfields as $key => $value) { - if (in_array($key, self::FORM_MECHANIC_FIELDS, true)) { + if (in_array($key, $excluded, true)) { continue; } - if (is_array($value)) { + if ($key === 'duedate' || $key === 'timelimit') { continue; } - $data->$key = $value; + $data->$key = self::normalize_multiselect_sentinel($value); } $data->duedate = self::decode_duedate($formfields); $data->timelimit = self::decode_timelimit($formfields); return $data; } + /** + * Mimic what MoodleQuickForm_autocomplete::exportValue() does for empty multi-selects: + * the form element emits '_qf__force_multiselect_submission' as a marker that the field + * was rendered but nothing was picked. moodleform normalizes that to an empty array + * before validation; we have to do the same since we parse the raw POST. + * + * @param mixed $value + * @return mixed + */ + private static function normalize_multiselect_sentinel($value) { + if ($value === '_qf__force_multiselect_submission') { + return []; + } + if (is_array($value)) { + return array_values(array_filter( + $value, + static fn($v) => $v !== '_qf__force_multiselect_submission' + )); + } + return $value; + } + /** * Convert a date_selector group `duedate[year|month|day|hour|minute]` to a unix timestamp. * From 0b356995ba697f356d3896f054666cf7917a598d Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 10:41:49 +0200 Subject: [PATCH 073/101] Fix, Type error depending on completionexpected. --- forms/form_field_decoder.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/forms/form_field_decoder.php b/forms/form_field_decoder.php index 621b6ddf..bb83b7b3 100644 --- a/forms/form_field_decoder.php +++ b/forms/form_field_decoder.php @@ -82,12 +82,13 @@ public static function from_form_fields(array $formfields): stdClass { if (in_array($key, $excluded, true)) { continue; } - if ($key === 'duedate' || $key === 'timelimit') { + if ($key === 'duedate' || $key === 'timelimit' || $key === 'completionexpected') { continue; } $data->$key = self::normalize_multiselect_sentinel($value); } - $data->duedate = self::decode_duedate($formfields); + $data->duedate = self::decode_date($formfields, 'duedate'); + $data->completionexpected = self::decode_date($formfields, 'completionexpected'); $data->timelimit = self::decode_timelimit($formfields); return $data; } @@ -115,22 +116,23 @@ private static function normalize_multiselect_sentinel($value) { } /** - * Convert a date_selector group `duedate[year|month|day|hour|minute]` to a unix timestamp. + * Convert a date_selector group `$field[year|month|day|hour|minute]` to a unix timestamp. * * @param array $formfields + * @param string $field * @return int */ - private static function decode_duedate(array $formfields): int { - $duedate = $formfields['duedate'] ?? null; - if (!is_array($duedate) || empty($duedate['year'])) { + private static function decode_date(array $formfields, string $field): int { + $dategroup = $formfields[$field] ?? null; + if (!is_array($dategroup) || empty($dategroup['year'])) { return 0; } return make_timestamp( - $duedate['year'], - $duedate['month'], - $duedate['day'], - $duedate['hour'] ?? 0, - $duedate['minute'] ?? 0 + $dategroup['year'], + $dategroup['month'], + $dategroup['day'], + $dategroup['hour'] ?? 0, + $dategroup['minute'] ?? 0 ); } From 70ccc734331f5d8771376475d973b22c5dcf80fa Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 11:05:04 +0200 Subject: [PATCH 074/101] Rename, tasks to mumie_tasks. --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 2 +- db/services.php | 4 ++-- externallib.php | 12 ++++++------ 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 2cc7a806..3196f89c 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 85c0b7e7..9e09baec 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface via Notification.exception.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","langController","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface via Notification.exception.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","langController","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 97e8ed0c..73c4cfd5 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -534,7 +534,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv require(['core/ajax', 'core/notification'], function(Ajax, Notification) { Ajax.call([{ - methodname: 'mod_mumie_create_multiple_tasks', + methodname: 'mod_mumie_create_multiple_mumie_tasks', args: { contextid: parseInt(contextId), section: section, diff --git a/db/services.php b/db/services.php index 661cd768..b4510d25 100644 --- a/db/services.php +++ b/db/services.php @@ -34,9 +34,9 @@ 'ajax' => true, 'type' => 'write', ], - 'mod_mumie_create_multiple_tasks' => [ + 'mod_mumie_create_multiple_mumie_tasks' => [ 'classname' => 'mod_mumie_external', - 'methodname' => 'create_multiple_tasks', + 'methodname' => 'create_multiple_mumie_tasks', 'classpath' => 'mod/mumie/externallib.php', 'description' => 'Creates multiple MUMIE Tasks at once with shared settings', 'ajax' => true, diff --git a/externallib.php b/externallib.php index 9c4177dc..694608d6 100644 --- a/externallib.php +++ b/externallib.php @@ -127,10 +127,10 @@ public static function submit_mumieduedate_form_returns() { } /** - * Describes the parameters for create_multiple_tasks webservice. + * Describes the parameters for create_multiple_mumie_tasks webservice. * @return external_function_parameters */ - public static function create_multiple_tasks_parameters() { + public static function create_multiple_mumie_tasks_parameters() { return new external_function_parameters([ 'contextid' => new external_value(PARAM_INT, 'Context id of the course'), 'section' => new external_value(PARAM_INT, 'Section number to add tasks to'), @@ -154,7 +154,7 @@ public static function create_multiple_tasks_parameters() { * @param string[] $tasksformdata One URL-encoded form POST per task * @return array Array of created course module ids */ - public static function create_multiple_tasks($contextid, $section, $tasksformdata) { + public static function create_multiple_mumie_tasks($contextid, $section, $tasksformdata) { global $CFG, $DB; require_once($CFG->dirroot . '/course/modlib.php'); @@ -165,7 +165,7 @@ public static function create_multiple_tasks($contextid, $section, $tasksformdat require_once($CFG->dirroot . '/mod/mumie/forms/mumie_task_validator.php'); $params = self::validate_parameters( - self::create_multiple_tasks_parameters(), + self::create_multiple_mumie_tasks_parameters(), [ 'contextid' => $contextid, 'section' => $section, @@ -219,10 +219,10 @@ public static function create_multiple_tasks($contextid, $section, $tasksformdat } /** - * Describes the return value for create_multiple_tasks webservice. + * Describes the return value for create_multiple_mumie_tasks webservice. * @return external_multiple_structure */ - public static function create_multiple_tasks_returns() { + public static function create_multiple_mumie_tasks_returns() { return new external_multiple_structure( new external_value(PARAM_INT, 'course module id') ); From 2a60d85e5ab2b5ea240e92d383405c19dbfa02a0 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 11:28:49 +0200 Subject: [PATCH 075/101] Remove dead DnD Code. --- classes/mumie_dndupload_processor.php | 335 -------------------------- lang/de/mumie.php | 3 - lang/en/mumie.php | 3 - lib.php | 51 ---- 4 files changed, 392 deletions(-) delete mode 100644 classes/mumie_dndupload_processor.php diff --git a/classes/mumie_dndupload_processor.php b/classes/mumie_dndupload_processor.php deleted file mode 100644 index bd55925c..00000000 --- a/classes/mumie_dndupload_processor.php +++ /dev/null @@ -1,335 +0,0 @@ -. - -/** - * This file describes a class used to create MUMIE Tasks via drag & drop. - * - * @package mod_mumie - * @copyright 2017-2025 integral-learning GmbH (https://www.integral-learning.de/) - * @author Tobias Goltz (tobias.goltz@integral-learning.de) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -namespace mod_mumie; - -defined('MOODLE_INTERNAL') || die; - -require_once($CFG->dirroot . '/auth/mumie/classes/mumie_server.php'); - -/** - * This processor is responsible for the creation of MUMIE Task that are being imported via dnd_handler. - * - * Some functions are taken and adapted from course/dnduploadlib.php. - * - * @package mod_mumie - * @copyright 2017-2020 integral-learning GmbH (https://www.integral-learning.de/) - * @author Tobias Goltz (tobias.goltz@integral-learning.de) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class mumie_dndupload_processor { - /** - * The number of the sections we want to add MUMIE Tasks to. - * @var int - */ - private $section; - - /** - * The data type of the uploaded file. - * @var string - */ - private $type; - - /** - * The uploaded file. - * @var \stdClass - */ - private $upload; - - /** - * The context of the current course. - * @var \context_course - */ - private $coursecontext; - - /** - * The course we want to create the MUMIE Tasks in. - * @var \stdClass - */ - private $course; - - /** - * The gradepool settings we're going to use for the new MUMIE Tasks. - * @var int - */ - private $gradepoolsettings; - - /** - * Constructor - * @param int $courseid Id of course we want to create Tasks in - * @param int $section The section number we are uploading to - * @param string $type The type identifier of the uploaded data - * @param stdClass $upload The object that has been uploaded - */ - public function __construct($courseid, $section, $type, $upload) { - $this->section = $section; - $this->type = $type; - $this->upload = $upload; - $this->gradepoolsettings = $this->get_course_gradepool_setting(); - $this->coursecontext = \context_course::instance($courseid); - global $COURSE; - $this->course = $COURSE; - } - - /** - * Start the creation of MUMIE Tasks for the uploaded data. - * - * We're hooking into the regular dnd_upload process. - * That's why the first uploaded problem needs to be handled differently form any further instances. - * @return int id of newly added grade item or false - */ - public function process() { - require_capability('moodle/course:manageactivities', $this->coursecontext); - require_sesskey(); - - if ($this->type == 'mumie/json') { - return $this->handle_single_upload(); - } - if ($this->type == 'mumie/jsonArray') { - return $this->handle_multi_upload(); - } - return false; - } - - /** - * Handle uploads of type mumie/json. Only a single Mumie Task will be created. - * This format is used by MUMIE servers. - * @return int id of newly added grade item - */ - private function handle_single_upload() { - global $CFG; - require_once($CFG->dirroot . '/auth/mumie/classes/mumie_server.php'); - $server = new \auth_mumie\mumie_server(); - $server->set_urlprefix($this->upload->server); - - $this->validate_upload_params($this->upload); - $this->validate_servers([$server]); - $this->create_missing_servers([$server]); - - $mumie = $this->create_mumie_from_uploadinstance($this->upload, $server); - $mumie->server = $server->get_urlprefix(); - - return mumie_add_instance($mumie, null); - } - - /** - * Handle uploads of type mumie/jsonArray. This function creates one or more instances of MUMIE Task. - * This format is used by LEMON servers. - * @return int id of newly added grade item - */ - private function handle_multi_upload() { - // This array holds unique server objects. - $servers = []; - $this->upload = (array) $this->upload; - foreach ($this->upload as $uploadinstance) { - $uploadinstance = json_decode($uploadinstance); - $this->validate_upload_params($uploadinstance); - $server = new \auth_mumie\mumie_server(); - $server->set_urlprefix($uploadinstance->server); - $servers[$uploadinstance->server] = $server; - } - - $this->validate_servers(array_values($servers)); - $this->create_missing_servers(array_values($servers)); - - $result; - $uploadlength = count($this->upload); - for ($i = 0; $i < $uploadlength; $i++) { - $uploadinstance = json_decode($this->upload[$i]); - $mumie = $this->create_mumie_from_uploadinstance($uploadinstance, $servers[$uploadinstance->server]); - $mumie->server = $servers[$uploadinstance->server]->get_urlprefix(); - if ($i == 0) { - $result = mumie_add_instance($mumie, null); - } else { - $module = $this->create_mumie_course_module($mumie); - } - } - - // Rebuild the course cache after update action. - rebuild_course_cache($this->course->id, true); - - // Return id of first mumie instance created. - return $result; - } - - /** - * Check whether all servers are valid MUMIE/Lemon servers. - * - * If a URL is not valid, an exception is thrown. - * - * @param \auth_mumie\mumie_server[] $servers The list of server we want to validate - */ - private function validate_servers($servers) { - foreach ($servers as $server) { - if (!$server->is_valid_mumie_server()) { - throw new \moodle_exception('mumie_form_server_not_existing', 'auth_mumie'); - } - } - } - - /** - * Make sure that there is a server configuration for every server used. If there aren't, create them. - * - * @param \auth_mumie\mumie_server[] $servers The list of servers for which we need server configurations. - */ - private function create_missing_servers($servers) { - $missingservers = array_filter( - $servers, - function ($server) { - return !$server->config_exists_for_url(); - } - ); - - if (empty($missingservers)) { - return; - } - - if (!has_capability("auth/mumie:addserver", \context_course::instance($this->course->id), $USER)) { - throw new \moodle_exception(get_string('server_config_missing', 'mod_mumie', $server->get_urlprefix())); - } - foreach ($missingservers as $server) { - $server->set_name($server->get_urlprefix()); - $server->upsert(); - } - } - - /** - * Get the value for MUMIE Task's gradepool setting in this course. - * - * @return int gradepool value for the imported MUMIE Tasks. - */ - private function get_course_gradepool_setting() { - global $DB, $COURSE; - $exitingtasks = array_values( - $DB->get_records(MUMIE_TASK_TABLE, ["course" => $COURSE->id]) - ); - $adminsetting = get_config('auth_mumie', 'defaultgradepool'); - if (count($exitingtasks) > 0) { - return $exitingtasks[0]->privategradepool; - } - if ($adminsetting != -1) { - return $adminsetting; - } - return null; - } - - /** - * Make sure that there are all necessary parameters set in the uploaded problem instance. - * - * @param \stdClass $uploadinstance a problem instance that's being imported - */ - private function validate_upload_params($uploadinstance) { - if ( - empty($uploadinstance->link) || empty($uploadinstance->path_to_coursefile) - || empty($uploadinstance->language) || empty($uploadinstance->name) - || empty($uploadinstance->server) || empty($uploadinstance->course) - ) { - throw new \moodle_exception('parameter_missing', 'mod_mumie'); - } - } - - /** - * Get a mumie object from the uploaded problem instance. - * - * @param \stdClass $uploadinstance The uploaded problem. - * @return \stdClass The mumie object that's going to be created. - */ - private function create_mumie_from_uploadinstance($uploadinstance) { - $mumie = new \stdClass(); - $mumie->taskurl = $uploadinstance->link . '?lang=' . $uploadinstance->language; - $mumie->mumie_coursefile = $uploadinstance->path_to_coursefile; - $mumie->language = $uploadinstance->language; - $mumie->course = $this->course->id; - $mumie->mumie_course = $uploadinstance->course; - $mumie->intro = ''; - $mumie->points = 100; - $mumie->name = \mod_mumie\locallib::get_default_name($uploadinstance) ?? $uploadinstance->name; - $mumie->privategradepool = $this->gradepoolsettings; - $mumie->isgraded = $uploadinstance->isGraded; - return $mumie; - } - - /** - * Create database entries for the new mumie instance and the linked course module. - * - * @param \stdClass $mumie The mumie object we want to add to the course. - */ - private function create_mumie_course_module($mumie) { - $mumieinstance = mumie_add_instance($mumie, null); - $cm = $this->create_course_module(); - $this->finish_setup_course_module($mumieinstance, $cm); - } - - /** - * Create a new course module in the database. - */ - private function create_course_module() { - global $CFG; - require_once($CFG->dirroot . '/course/modlib.php'); - [$module, $context, $cw, $cm, $data] = prepare_new_moduleinfo_data($this->course, 'mumie', $this->section); - $data->coursemodule = $data->id = add_course_module($data); - return $data; - } - - /** - * Set missing values for course_module and finish the setup. - * - * @param int $instanceid id of newly created mumie instance - * @param \stdClass $cm Newly created coursemodule instance - */ - protected function finish_setup_course_module($instanceid, $cm) { - global $DB; - - if (!$instanceid) { - // Something has gone wrong - undo everything we can. - course_delete_module($cm->id); - throw new \moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name); - } - - // Note the section visibility. - $visible = get_fast_modinfo($this->course)->get_section_info($this->section)->visible; - - $DB->set_field('course_modules', 'instance', $instanceid, ['id' => $cm->id]); - - course_add_cm_to_section($this->course, $cm->id, $this->section); - - set_coursemodule_visible($cm->id, $visible); - if (!$visible) { - $DB->set_field('course_modules', 'visibleold', 1, ['id' => $cm->id]); - } - - // Retrieve the final info about this module. - $info = get_fast_modinfo($this->course); - if (!isset($info->cms[$cm->id])) { - // The course module has not been properly created in the course - undo everything. - course_delete_module($cm->id); - throw new \moodle_exception('errorcreatingactivity', 'moodle', '', "mod_mumie"); - } - $mod = $info->get_cm($cm->id); - - // Trigger course module created event. - $event = \core\event\course_module_created::create_from_cm($mod); - $event->trigger(); - } -} diff --git a/lang/de/mumie.php b/lang/de/mumie.php index ad62bc13..2d6bb37d 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -30,9 +30,6 @@

Bitte beachten Sie:
Noten für MUMIE Tasks werden nur aktualisiert, wenn sie im Moodle-Gradebook angezeigt werden. Wenn Sie aktuelle Informationen über den Aktivitätsabschluss aller Studierenden sehen möchten, sollten zu daher zuvor die Bewerterübersicht öffnen.'; -$string['dnd_addmessage'] = 'MUMIE-Task hinzufügen'; -$string['dnd_addmessage_multiple'] = 'MUMIE-Tasks hinzufügen'; -$string['dndupload_message'] = 'Als neue MUMIE Task hinzufügen'; $string['gradetopassmustbeset'] = 'Die Bestehensgrenze kann nicht 0 sein, da der Aktivitätsabschluss vom Erreichen dieser Grenze abhängig ist. Bitte geben Sie daher einen Wert über 0 ein.'; $string['gradetopassnotset'] = 'Dieser Test hat keine Bestehensgrenze.'; $string['modulename'] = 'MUMIE Task'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index e38eae13..062b3e38 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -28,9 +28,6 @@ $string['completionpass_help'] = 'If enabled, this activity is considered completed when the student receives a passing grade, with the pass grade set in the gradebook.

Please Note:
Grades for MUMIE Tasks are only updated, when the gradebook is opened. If you want the current completion status of all students, remember to open the gradebook overview page first'; -$string['dnd_addmessage'] = 'Add MUMIE Task here'; -$string['dnd_addmessage_multiple'] = 'Add MUMIE Tasks here'; -$string['dndupload_message'] = 'Add as a new MUMIE Task'; $string['gradetopassmustbeset'] = 'Grade to pass cannot be zero as this activity has its completion method set to require passing grade. Please set a non-zero value.'; $string['gradetopassnotset'] = 'This MUMIE task does not have a grade to pass set so you cannot use this option. Please use the require grade setting instead.'; $string['modulename'] = 'MUMIE Task'; diff --git a/lib.php b/lib.php index aa88e79b..fd643b25 100644 --- a/lib.php +++ b/lib.php @@ -25,7 +25,6 @@ use mod_mumie\locallib; use mod_mumie\mumie_calendar_service; -use mod_mumie\mumie_dndupload_processor; use mod_mumie\mumie_duedate_extension; defined('MOODLE_INTERNAL') || die; @@ -314,56 +313,6 @@ function mumie_get_completion_state($course, $cm, $userid, $type) { return false; } -/** - * Register the ability to handle drag and drop of datatransfertype mumie/json - * @return array containing details of the files / types the mod can handle - */ -function mumie_dndupload_register() { - return [ - 'addtypes' => [ - [ - 'identifier' => 'mumie/json', 'datatransfertypes' => ['mumie/json', 'mumie/json'], - 'addmessage' => get_string('dnd_addmessage', 'mod_mumie'), - 'namemessage' => '', - 'priority' => 1], - [ - 'identifier' => 'mumie/jsonArray', 'datatransfertypes' => ['mumie/jsonArray', 'mumie/jsonArray'], - 'addmessage' => get_string('dnd_addmessage_multiple', 'mod_mumie'), - 'namemessage' => '', - 'priority' => 1], - ], - 'types' => [ - [ - 'identifier' => 'mumie/json', - 'message' => get_string('dndupload_message', 'mod_mumie'), - 'noname' => true], - [ - 'identifier' => 'mumie/jsonArray', - 'message' => get_string('dndupload_message', 'mod_mumie'), - 'noname' => true], - ], - ]; -} - -/** - * Handle content that has been uploaded - * @param object $uploadinfo details of the content that has been uploaded - * @return int instance id of the newly created mod - */ -function mumie_dndupload_handle($uploadinfo) { - global $CFG, $COURSE, $USER; - - $courseid = required_param('course', PARAM_INT); - $section = required_param('section', PARAM_INT); - $type = required_param('type', PARAM_TEXT); - - $context = context_module::instance($uploadinfo->coursemodule); - $upload = json_decode(clean_param($uploadinfo->content, PARAM_RAW)); - require_once($CFG->dirroot . '/mod/mumie/classes/mumie_dndupload_processor.php'); - $processor = new mumie_dndupload_processor($courseid, $section, $type, $upload); - $result = $processor->process(); - return $result; -} /** * Get mumieserver_form as a fragment From 56c4e6ea05b0a5df040f83e46b71a947e976746c Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 11:36:57 +0200 Subject: [PATCH 076/101] Refactoring, reuse buildUrl instead copy Code. --- amd/src/mod_form.js | 71 +++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 48 deletions(-) diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 73c4cfd5..1031de31 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -202,38 +202,34 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv * Builds the URL to the Problem Selector * @returns {string} URL to the Problem Selector */ - function buildURL() { - const gradingType = taskController.getGradingType(); - const selection = taskController.getDelocalizedTaskLink(); + function buildURL(multiSelect = false) { + const gradingType = multiSelect ? 'all' : taskController.getGradingType(); const selectedServer = serverController.getSelectedServer().urlprefix; const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer); - if (useSSO) { - return '/auth/mumie/problem_selector.php?' + - 'org=' + - mumieOrg + - '&serverurl=' + - encodeURIComponent(selectedServer) + - '&problemlang=' + - langController.getSelectedLanguage() + - '&origin=' + encodeURIComponent(window.location.origin) + - '&gradingtype=' + gradingType + - '&contextid=' + contextId + - (selection ? '&selection=' + selection : ''); - } - return lmsSelectorUrl + - '/lms-problem-selector?' + - 'org=' + - mumieOrg + - '&serverUrl=' + - encodeURIComponent(selectedServer) + - '&problemLang=' + - langController.getSelectedLanguage() + + + const base = useSSO + ? '/auth/mumie/problem_selector.php?' + + 'org=' + mumieOrg + + '&serverurl=' + encodeURIComponent(selectedServer) + + '&problemlang=' + langController.getSelectedLanguage() + + '&origin=' + encodeURIComponent(window.location.origin) + + '&gradingtype=' + gradingType + + '&contextid=' + contextId + : lmsSelectorUrl + '/lms-problem-selector?' + + 'org=' + mumieOrg + + '&serverUrl=' + encodeURIComponent(selectedServer) + + '&problemLang=' + langController.getSelectedLanguage() + '&origin=' + encodeURIComponent(window.location.origin) + '&uiLang=' + systemLanguage + '&gradingType=' + gradingType + '&multiCourse=true' + - '&worksheet=true' + - (selection ? '&selection=' + selection : ''); + '&worksheet=true'; + + if (multiSelect) { + return base + (useSSO ? '&multiselect=true' : '&multiSelect=true'); + } + const selection = taskController.getDelocalizedTaskLink(); + return selection ? base + '&selection=' + selection : base; } /** @@ -267,28 +263,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv multiProblemSelectorButton.onclick = function(e) { e.preventDefault(); - const selectedServer = serverController.getSelectedServer().urlprefix; - const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer) - ? '/auth/mumie/problem_selector.php?' + - 'org=' + mumieOrg + - '&serverurl=' + encodeURIComponent(selectedServer) + - '&problemlang=' + langController.getSelectedLanguage() + - '&origin=' + encodeURIComponent(window.location.origin) + - '&gradingtype=all' + - '&contextid=' + contextId + - '&multiselect=true' - : lmsSelectorUrl + - '/lms-problem-selector?' + - 'org=' + mumieOrg + - '&serverUrl=' + encodeURIComponent(selectedServer) + - '&problemLang=' + langController.getSelectedLanguage() + - '&origin=' + encodeURIComponent(window.location.origin) + - '&uiLang=' + systemLanguage + - '&gradingType=all' + - '&multiCourse=true' + - '&worksheet=true' + - '&multiSelect=true'; - problemSelectorWindow = window.open(multiSelectorUrl, "_blank", 'toolbar=0,location=0,menubar=0'); + problemSelectorWindow = window.open(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0'); }; }, disable: function() { From 54fde324c0192075bf65c8c63a80de13aad6b262 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 11:52:08 +0200 Subject: [PATCH 077/101] empty Name, MUMIE course, MUMIE problem, field inf form, when multi select is selected. --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 3196f89c..c5554dc4 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(function(){const gradingType=taskController.getGradingType(),selection=taskController.getDelocalizedTaskLink(),selectedServer=serverController.getSelectedServer().urlprefix;return shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId+(selection?"&selection="+selection:""):lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true"+(selection?"&selection="+selection:"")}(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault();const selectedServer=serverController.getSelectedServer().urlprefix,multiSelectorUrl=shouldUseSSO(lmsSelectorUrl,selectedServer)?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype=all&contextid="+contextId+"&multiselect=true":lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType=all&multiCourse=true&worksheet=true&multiSelect=true";problemSelectorWindow=window.open(multiSelectorUrl,"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.removeAttribute("required");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 9e09baec..73e3a5f5 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @returns {string} URL to the Problem Selector\n */\n function buildURL() {\n const gradingType = taskController.getGradingType();\n const selection = taskController.getDelocalizedTaskLink();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n if (useSSO) {\n return '/auth/mumie/problem_selector.php?' +\n 'org=' +\n mumieOrg +\n '&serverurl=' +\n encodeURIComponent(selectedServer) +\n '&problemlang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId +\n (selection ? '&selection=' + selection : '');\n }\n return lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' +\n mumieOrg +\n '&serverUrl=' +\n encodeURIComponent(selectedServer) +\n '&problemLang=' +\n langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true' +\n (selection ? '&selection=' + selection : '');\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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 const selectedServer = serverController.getSelectedServer().urlprefix;\n const multiSelectorUrl = shouldUseSSO(lmsSelectorUrl, selectedServer)\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=all' +\n '&contextid=' + contextId +\n '&multiselect=true'\n : lmsSelectorUrl +\n '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=all' +\n '&multiCourse=true' +\n '&worksheet=true' +\n '&multiSelect=true';\n problemSelectorWindow = window.open(multiSelectorUrl, \"_blank\", 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.removeAttribute('required');\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface via Notification.exception.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","shouldUseSSO","problemSelectorUrl","selectedServerUrl","URL","onclick","open","gradingType","getGradingType","selection","getDelocalizedTaskLink","selectedServer","urlprefix","encodeURIComponent","langController","getSelectedLanguage","location","buildURL","onclose","e","preventDefault","multiSelectorUrl","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"mappings":"AAAAA,4BAAO,CAAC,SAAU,iBAAkB,qBAAsB,iCAAkC,cACxF,iBACUC,gBAAkBC,SAASC,eAAe,wBAC1CC,cAAgBF,SAASG,kBAAkB,wBAAwB,OACrEC,eACAC,eACAC,gBAGEC,mBAAsB,iBAElBC,iBAAmBR,SAASC,eAAe,wBAC3CQ,WAAaT,SAASC,eAAe,8BAKlCS,mBACuB,MAArBD,WAAWE,eAMbC,mDACYF,cAEbF,iBAAiBK,aAAa,WAAY,YAC1CL,iBAAiBG,MAAQ,aAEzBH,iBAAiBM,gBAAgB,YAKN,cAA3BN,iBAAiBG,OACjBX,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,sBAAsBc,MAAMC,QALpC,OAMhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QANzC,OAOhBhB,SAASC,eAAe,oBAAoBc,MAAMC,QAPlC,OAQhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QARvC,QASkB,YAA3BR,iBAAiBG,OACxBX,SAASC,eAAe,oBAAoBc,MAAMC,QAAU,GAC5DhB,SAASC,eAAe,yBAAyBc,MAAMC,QAAU,GAEjEhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAbzC,OAchBhB,SAASC,eAAe,sBAAsBc,MAAMC,QAdpC,OAehBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAfzC,QAgBkB,cAA3BR,iBAAiBG,QACxBX,SAASC,eAAe,sBAAsBc,MAAMC,QAAU,GAC9DhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,oBAAoBc,MAAMC,QApBlC,OAqBhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QArBvC,OAsBhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAtBzC,cAyBdC,6CAAiBjB,SAClBkB,cAAc,+FADIC,sBAEjBC,QAAQ,SACVH,eAAgB,OACVI,KAAkC,YAA3Bb,iBAAiBG,SAC9BM,eAAeF,MAAMC,QAAUK,KAAO,GA9BtB,QA+BXA,KAAM,OACDC,wBAA0BL,eAAeC,cAAc,sCACzDI,yBAA2BA,wBAAwBC,UACnDD,wBAAwBC,SAAU,EAClCD,wBAAwBE,cAAc,IAAIC,MAAM,oBAMzD,CACHC,KAAM,WACFlB,iBAAiBmB,SAAW,WACxBf,0BAEJgB,OAAOC,iBAAiB,QAAQ,KAC5BjB,4BAEJA,0BAEJkB,oBAAqBlB,uBACrBF,WAAYA,WACZqB,mBAAoB,SAASC,UACzBvB,WAAWE,MAAQqB,SAAW,IAAM,KAExCC,mBAAoB,kBACTxB,WAAWE,QAjFF,GAsFtBuB,iBAAoB,eAClBC,sBACEC,eAAiBpC,SAASC,eAAe,mBAExC,CACHyB,KAAM,SAASW,WACXF,gBAAkBE,WAEtBC,kBAAmB,iBACTC,mBAAqBH,eAAeI,QAAQJ,eAAeK,eAAeC,YACzEP,gBAAgBQ,MAAKC,QAAUA,OAAOC,OAASN,sBAE1DO,QAAS,WACLV,eAAeW,UAAW,WA2qBZC,WACfA,KAAKC,YACRD,KAAKE,YAAYF,KAAKC,YA5qBlBE,CAAiBf,kBAdH,GAmBpBgB,0BAA6B,iBACzBC,sBAAwBrD,SAASC,eAAe,uBAChDqD,2BAA6BtD,SAASC,eAAe,qCACvDsD,4BACEC,SAAWxD,SAASG,kBAAkB,aAAa,GAAGQ,eAQnD8C,aAAaC,UACbH,uBAGLA,sBAAsBI,YAAYC,KAAKC,UAAUH,UAAWtD,yBAOvD0D,kBAAYC,+DAAU,GAC3BN,aAAa,CACTO,SAAS,EACTD,QAASA,mBAkBRE,qBACLrC,OAAOC,iBAAiB,WAAYqC,WAC5BA,MAAMC,SAAW/D,4BAGfgE,UAAYR,KAAKS,MAAMH,MAAMI,SAE/BC,MAAMC,QAAQJ,kBACdK,eAAeC,kBAAkBN,WACjCN,mBACAlC,OAAO+C,YAKPC,yBAAyBR,WACzBN,cACAlC,OAAO+C,QAYfE,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN,+BACPC,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBrB,QAASoB,EAAE,GACXE,KAAM,YAEXC,KAAKP,aAAaQ,cAnBnB,MAAOC,mBA5Bb/B,aAAa,CACTO,SAAS,EACTD,+DAHuB,KA8BnB0B,CAAYD,MAAMzB,aAEvB,YAmEE2B,aAAaC,mBAAoBC,0BAC/B,IAAIC,IAAIF,oBAAoBxB,SAAW,IAAI0B,IAAID,mBAAmBzB,aAGtE,CACHzC,KAAM,WACF2B,sBAAsByC,QAAU,WAC5BvC,sBAAwB3B,OAAOmE,sBAjDjCC,YAAcvB,eAAewB,iBAC7BC,UAAYzB,eAAe0B,yBAC3BC,eAAiBlE,iBAAiBI,oBAAoB+D,iBAC7CX,aAAatF,eAAgBgG,gBAEjC,wCAEH5C,SACA,cACA8C,mBAAmBF,gBACnB,gBACAG,eAAeC,sBACf,WAAaF,mBAAmB1E,OAAO6E,SAAStC,QAChD,gBAAkB6B,YAClB,cAAgB1F,WACf4F,UAAY,cAAgBA,UAAY,IAE1C9F,eAAAA,6BAGHoD,SACA,cACA8C,mBAAmBF,gBACnB,gBACAG,eAAeC,sBACf,WAAaF,mBAAmB1E,OAAO6E,SAAStC,QAChD,WAAa9D,eACb,gBAAkB2F,YAVf5F,oCAaF8F,UAAY,cAAgBA,UAAY,IAmBDQ,GAAY,WAGpD9E,OAAO+E,QAAU,WACb7C,eAGJlC,OAAOC,iBAAiB,gBAAgB,WACpCiC,iBACD,GAEHG,qBAEAX,2BAA2BwC,QAAU,SAASc,GAC1CA,EAAEC,uBACIT,eAAiBlE,iBAAiBI,oBAAoB+D,UACtDS,iBAAmBpB,aAAatF,eAAgBgG,gBAChD,wCACW5C,SACT,cAAgB8C,mBAAmBF,gBACnC,gBAAkBG,eAAeC,sBACjC,WAAaF,mBAAmB1E,OAAO6E,SAAStC,QAJlD,8BAMkB7D,UAChB,oBACFF,eAAAA,6BAEWoD,SACT,cAAgB8C,mBAAmBF,gBACnC,gBAAkBG,eAAeC,sBACjC,WAAaF,mBAAmB1E,OAAO6E,SAAStC,QAChD,WAAa9D,eANfD,oEAWNmD,sBAAwB3B,OAAOmE,KAAKe,iBAAkB,SAAU,oCAGxEhE,QAAS,WACLO,sBAAsBN,UAAW,IApLV,YAkM1B6B,yBAAyBmC,sCACxB/E,UAAgC,IAArB+E,QAAQ/E,SACnBgF,qCAAYD,QAAQC,2DAAa,KACvCC,iBAAiBC,UAAUH,QAAQI,oBACnCZ,eAAea,YAAYL,QAAQM,UACnC5C,eAAe6C,aAAaP,QAAQQ,KAAMR,QAAQM,SAAUN,QAAQlE,MACpE4B,eAAe+C,YAAYxF,UAC3ByF,oBAAoBC,aAAaV,iBAG/BC,iBAAoB,iBAChBU,eAAiB3H,SAASC,eAAe,mBACzC2H,eAAiB5H,SAASG,kBAAkB,oBAAoB,YAgB7D0H,mDACCC,eAAiBb,iBAAiBc,oBAClCC,iBAAmBzB,eAAeC,sBACnCsB,gBAAmBE,mBAGxBL,eAAehH,oCAAQmH,eAAejF,KACjCF,MAAKsF,aAAeA,YAAYZ,WAAaW,2DAD3BE,sBAC8CvH,aAGlE,CACHe,KAAM,WACFmG,oBAEJE,kBAAmB,kBACC7F,iBAAiBI,oBAAoB6F,QACtCxF,MAAKyF,QAAUA,OAAOC,aAAeT,eAAejH,SAEvEuG,UAAW,SAASoB,gBA1BMD,WAAAA,WA2BDC,WA1BzBV,eAAejH,MAAQ0H,WACvBR,qBAZkB,GA0CpBtB,eAAkB,iBACdgC,aAAevI,SAASC,eAAe,qBACtC,CACHuG,oBAAqB,kBACV+B,aAAa5H,OAExByG,YAAa,SAASoB,MAClBD,aAAa5H,MAAQ6H,OAPT,GAYlB/D,eAAkB,iBACdgE,mBAAqBzI,SAASG,kBAAkB,WAAW,GAC3DuI,SAAW1I,SAASC,eAAe,WACnC0I,mBAAqB3I,SAASC,eAAe,oCAc1C2I,yBAAyBC,eAC9BF,mBAAmBhI,MAAQkI,uBAQtBC,cAAcvB,KAAMF,gBACnBwB,uBAWYtB,KAAMF,iBACjBE,KAnCuB,SAmCYF,SAZpB0B,CAAaxB,KAAMF,UACzCoB,mBAAmB9H,MAAQkI,cAC3BD,yBAAyBC,wBAwCpBnE,kBAAkBsE,aACjBC,WAAajJ,SAASG,kBAAkB,qBAAqB,GAC7D+I,QAAUlJ,SAASC,eAAe,gCACpCgJ,aACAA,WAAWtI,MAAQiD,KAAKC,UAAUmF,QAElCE,QAAS,OACHC,cAAgBH,MAAMI,KAAIC,aACtBC,aAAetJ,SAASuJ,cAAc,aAC5CD,aAAaE,YAAcH,KAAKxG,KACzByG,gBAEXJ,QAAQO,UAAY,SACdC,eAAiB1J,SAASuJ,cAAc,OACxCI,SAAW3J,SAASuJ,cAAc,MACxC1E,QAAQ,CAAC,aAAa,SAAS+E,KAC3BA,IAAIC,WAAW,6BAA8B,YAAab,MAAMc,QAC3DC,MAAK,SAASC,OACXN,eAAeF,YAAcQ,YAGzCL,SAAS5I,MAAMkJ,OAAS,kBACxBd,cAAce,SAAQZ,cAAgBK,SAASQ,YAAYb,gBAC3DJ,QAAQiB,YAAYT,gBACpBR,QAAQiB,YAAYR,UACpBT,QAAQnI,MAAMC,QAAU,cAEtBoJ,UAAYpK,SAASC,eAAe,WAC1CmK,UAAUrH,UAAW,EACrBqH,UAAUtJ,gBAAgB,kBACpBuJ,mBAAqBrK,SAASC,eAAe,iBAC/CoK,oBACAA,mBAAmBC,iBAAiB,gDAC/BJ,SAAQK,oBAAuBA,kBAAkBxJ,MAAMC,QAAU,gBAEpEwJ,eAAiBxK,SAASkB,cAAc,0BAC1CsJ,iBACAA,eAAezJ,MAAMC,QAAU,cAsEhC,CACHU,KAAM,WACFkH,yBAAyBH,mBAAmB9H,QAEhD2G,aAAc,SAASC,KAAMF,SAAUxE,YAC7BoG,WAAajJ,SAASG,kBAAkB,qBAAqB,GAC/D8I,aACAA,WAAWtI,MAAQ,UAEjBuI,QAAUlJ,SAASC,eAAe,6BACpCiJ,UACAA,QAAQnI,MAAMC,QAAU,OACxBkI,QAAQO,UAAY,UAElBW,UAAYpK,SAASC,eAAe,WACtCmK,YACAA,UAAUrH,UAAW,EACrBqH,UAAUvJ,aAAa,WAAY,mBAEjCwJ,mBAAqBrK,SAASC,eAAe,iBAC/CoK,oBACAA,mBAAmBC,iBAAiB,gDAC/BJ,SAAQK,oBAAuBA,kBAAkBxJ,MAAMC,QAAU,YAEpEwJ,eAAiBxK,SAASkB,cAAc,0BAC1CsJ,iBACAA,eAAezJ,MAAMC,QAAU,IAEnC8H,cAAcvB,KAAMF,mBAlMRxE,MAChB6F,SAAS/H,MAAQkC,KAkMb4H,CAAW5H,OAEf2E,YAAa,SAASxF,UAClBzB,mBAAmBwB,mBAAmBC,2BAtJpCe,SAAWxC,mBAAmBG,aACpCV,SAASC,eAAe,aAAa8C,SAAWA,SAChD/C,SAASC,eAAe,gBAAgB8C,SAAWA,SACnD/C,SAASC,eAAe,eAAe8C,SAAWA,SAClDxC,mBAAmBuB,sBAmJf4I,IAEJzE,eAAgB,iBACNjE,SAAWzB,mBAAmB0B,2BACnB,MAAbD,SACO,SACa,MAAbA,SACA,WAEJ,OAEXmE,uBAAwB,kBA7KJoB,KA8KMkB,mBAAmB9H,OA7KpCgK,SA5CqB,UA6CnBpD,KAAKqD,MA7Cc,UA6CmB,GAE1CrD,SAJaA,MAgLpB7C,kBAAmBA,kBACnBmG,cAAe,iBACL5B,WAAajJ,SAASG,kBAAkB,qBAAqB,UAC5D8I,cAAgBA,WAAWtI,OAEtCmK,4DAlFM7B,WAAajJ,SAASG,kBAAkB,qBAAqB,GAC7D4K,uCAAW/K,SAASG,kBAAkB,UAAU,2CAArC6K,sBAAyCrK,MACpDsK,QAAUC,SAAS,IAAIC,gBAAgBvJ,OAAO6E,SAAS2E,QAAQC,IAAI,YAAc,GACjFC,aAAetL,SAASC,eAAe,mBACvCsL,KAAOD,cAAgBA,aAAalK,QAAQ,QAC5C4H,MAAQpF,KAAKS,MAAM4E,WAAWtI,OAE9B6K,cAAgBxC,MAAMI,KAAIC,OAC5BzE,yBAAyByE,eAjCJkC,YACnBE,eAAiBlH,MAAMmH,KAAKH,KAAKjB,iBAAiB,cACxDmB,eAAevB,SAAQyB,QAAWA,MAAM5I,UAAW,eAEzC6I,KAAO,CAAC,UAAW,kCAClBrH,MAAMmH,KAAK,IAAIG,SAASN,OAC1BO,QAAOC,WAAEC,iBAAUJ,KAAKjB,SAASqB,QACjC5C,KAAI6C,YAAED,IAAKrL,oBAAW2F,mBAAmB0F,KAAO,IAAM1F,mBAAmB3F,UACzEuL,KAAK,aAEVT,eAAevB,SAAQyB,QAAWA,MAAM5I,UAAW,MAwB5CoJ,CAAoBZ,SAK/B7G,kBAAkBsE,OAElBnE,QAAQ,CAAC,YAAa,sBAAsB,SAASuH,KAAMC,cACvDD,KAAKE,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CACFC,UAAWvB,SAAS5K,WACpB2K,QAASA,QACTyB,cAAelB,kBAEnB,GAAGtG,MAAK,WACRtD,OAAO6E,SAASkG,KAAOC,EAAEC,IAAIC,QAAU,uBAAyB/B,YACjEzF,KAAK+G,aAAa9G,gBA5KT,GAyOlBwH,wBAA2B,iBACvBC,wBAA0BhN,SAASG,kBAAkB,6BACrD8M,uBAAyBjN,SAASG,kBAAkB,kCAAkC,OACxF+M,iBAAmB,SACjBC,oBAAsBnN,SAASG,kBAAkB,yBACjDiN,cAAgBpN,SAASG,kBAAkB,wBAAwB,OACrEkN,gBAAkB,SAChBC,cAAgBtN,SAASG,kBAAkB,qCA4CxCoN,gCACLP,wBAAwB9C,SAAQ,SAASsD,UACrCA,SAAS7L,SAAW,WACX6L,SAASjM,QAGV2L,iBAAiBO,KAAKD,SAAS7M,OAF/BuM,iBAAmBA,iBAAiBpB,QAAO9I,MAAQA,OAASwK,SAAS7M,QAIzEsM,uBAAuBtM,MAAQiD,KAAKC,UAAUqJ,mCAlBhDQ,gBAAkBnJ,MAAMmH,KAAKsB,yBAC9BW,MAAKH,UAA+B,YAAnBA,SAAS7M,OAAuB6M,SAASjM,UAC/DvB,SAASsK,iBAAiB,kDAAkDJ,SAAQ,SAASlH,MACzFA,KAAKjC,MAAMC,QAAU0M,gBAAkB,GAAK,UAgBxCE,aA+BL,CACHlM,KAAM,WAnENyL,oBAAoBjD,SAAQ,SAASsD,UACjCA,SAAS7L,SAAW,WACX6L,SAASjM,QAGV8L,gBAAgBI,KAAKD,SAAS7M,OAF9B0M,gBAAkBA,gBAAgBvB,QAAO9I,MAAQA,OAASwK,SAAS7M,QAIvEyM,cAAczM,MAAQiD,KAAKC,UAAUwJ,qBA8DzCE,gCAzBJD,cAAcpD,SAAQ,SAAS2D,iBAC3BA,gBAAgBlM,SAAW,WAClBkM,gBAAgBtM,QAQjB4L,oBAAoBjD,SAAQ,SAAS4D,kBAhE5BC,MAAOC,QAiERF,aAAaG,aAAa,aAAeJ,gBAAgBlN,QACzDmN,aAAavM,SAAU,EAlEtBwM,MAmEeV,gBAnERW,QAmEyBF,aAAanN,MAlE7DoN,MAAMpD,SAASqD,UAChBD,MAAMN,KAAKO,aAuDHb,oBAAoBjD,SAAQ,SAAS4D,cAC7BA,aAAaG,aAAa,aAAeJ,gBAAgBlN,QACzDmN,aAAavM,SAAU,EACvB8L,gBAAkBA,gBAAgBvB,QAAO9I,MAAQ8K,aAAanN,QAAUqC,WAWpFoK,cAAczM,MAAQiD,KAAKC,UAAUwJ,uBAtFpB,GAoG3B5F,oBAAuB,iBACnByG,iBAAmBlO,SAASC,eAAe,4BAC1C,CACHyH,aAAc,SAASV,WACfA,UACAkH,iBAAiBrN,aAAa,QAAS+C,KAAKC,UAAUmD,YAEtDkH,iBAAiBpN,gBAAgB,WAPpB,YAiBpBqN,qBAAqBC,UAC1BvJ,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACNoJ,SACPnJ,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBrB,QAASoB,EAAE,GAAK,MAAQjF,cAAc+N,aAAa,SAAW,OAC9D5I,KAAM,eAEXC,KAAKP,aAAaQ,cAEzBrD,iBAAiBY,UACjBM,0BAA0BN,gBAGvB,CACHpB,KAAM,SAAS2M,eAAgBC,eAAgB9F,MAC3CpI,eAAiBkO,eACjBjO,eAAiBmI,KACjBlI,UAAY+N,qBACNE,OAASvO,SAASC,eAAe,WAAWgO,aAAa,SACzD9L,gBAAkByB,KAAKS,MAAMrE,SAASG,kBAAkB,0BAA0B,GAAGQ,OACvF4N,QAyD+E,KAAhFvO,SAASG,kBAAkB,wBAAwB,GAAG8N,aAAa,SAxDlEE,qBAAqB,6BACbhM,gBAAgB2H,QAGxB5H,iBAAiBR,KAAKS,iBACtB8E,iBAAiBvF,OACjB+C,eAAe/C,OACfqL,wBAAwBrL,OACxB0B,0BAA0B1B,OAC1BnB,mBAAmBmB,QAPnByM,qBAAqB,6BASrBpO,iBACA8E,QAAQ,CAAC,mCAAmC,SAAS2J,aACjDA,YAAY9M,KAAK3B,gBAAiBO,oBAIpCgL,aAAetL,SAASC,eAAe,mBACvCsL,KAAOD,cAAgBA,aAAalK,QAAQ,WAC9CmK,KAAM,KACFkD,eAAgB,QACdC,aAAe1O,SAASC,eAAe,aACzCyO,cACAA,aAAa7M,iBAAiB,SAAS,WACnC4M,eAAgB,KAGxBlD,KAAK1J,iBAAiB,UAAU,SAAS+E,GACjC6H,cACAA,eAAgB,EAGhBhK,eAAeoG,kBACfjE,EAAEC,iBACFpC,eAAeqG"} \ 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface via Notification.exception.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 1031de31..81eb15fa 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -200,6 +200,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv /** * Builds the URL to the Problem Selector + * @param {boolean} multiSelect Whether to build a multi-select URL * @returns {string} URL to the Problem Selector */ function buildURL(multiSelect = false) { @@ -443,7 +444,12 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv } const nameField = document.getElementById('id_name'); nameField.disabled = true; + nameField.value = ''; nameField.removeAttribute('required'); + const taskDisplayElem = document.getElementById('id_task_display_element'); + if (taskDisplayElem) { taskDisplayElem.value = ''; } + const courseNameElem = document.getElementById('id_mumie_course'); + if (courseNameElem) { courseNameElem.value = ''; } const nameFieldContainer = document.getElementById('fitem_id_name'); if (nameFieldContainer) { nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]') From 4603f7e97b953f0d65702789494317e92af9464d Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 12:17:54 +0200 Subject: [PATCH 078/101] Disable multi-select button in edit mode and clear fields on multi-select switch --- mod_form.php | 1 + 1 file changed, 1 insertion(+) diff --git a/mod_form.php b/mod_form.php index e5f72bf5..9c116465 100644 --- a/mod_form.php +++ b/mod_form.php @@ -538,6 +538,7 @@ public function set_data($data): void { $this->set_general_server_data($data, $mform); // This option must not be changed to avoid messing with grades in the database. $mform->updateElementAttr("mumie_complete_course", ["disabled" => "disabled"]); + $mform->updateElementAttr("multi_problem_selector_btn", ["disabled" => "disabled"]); $this->set_grade_data($data, $mform); parent::set_data($data); } From e3d85793ea1d9392ae88a528530e2b0f1ab585d7 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 12:35:35 +0200 Subject: [PATCH 079/101] Deuglyfie Error Messages mod_form. --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 10 ++++++++-- lang/de/mumie.php | 2 +- lang/en/mumie.php | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index c5554dc4..18960637 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail(Notification.exception)}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){Notification.addNotification({message:error.message,type:"error"})}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 73e3a5f5..550b7a75 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface via Notification.exception.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(Notification.exception);\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a top-of-page notification with the\n * validator's localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n Notification.addNotification({\n message: error.message,\n type: 'error',\n });\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"mappings":"AAAAA,4BAAO,CAAC,SAAU,iBAAkB,qBAAsB,iCAAkC,cACxF,iBACUC,gBAAkBC,SAASC,eAAe,wBAC1CC,cAAgBF,SAASG,kBAAkB,wBAAwB,OACrEC,eACAC,eACAC,gBAGEC,mBAAsB,iBAElBC,iBAAmBR,SAASC,eAAe,wBAC3CQ,WAAaT,SAASC,eAAe,8BAKlCS,mBACuB,MAArBD,WAAWE,eAMbC,mDACYF,cAEbF,iBAAiBK,aAAa,WAAY,YAC1CL,iBAAiBG,MAAQ,aAEzBH,iBAAiBM,gBAAgB,YAKN,cAA3BN,iBAAiBG,OACjBX,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,sBAAsBc,MAAMC,QALpC,OAMhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QANzC,OAOhBhB,SAASC,eAAe,oBAAoBc,MAAMC,QAPlC,OAQhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QARvC,QASkB,YAA3BR,iBAAiBG,OACxBX,SAASC,eAAe,oBAAoBc,MAAMC,QAAU,GAC5DhB,SAASC,eAAe,yBAAyBc,MAAMC,QAAU,GAEjEhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAbzC,OAchBhB,SAASC,eAAe,sBAAsBc,MAAMC,QAdpC,OAehBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAfzC,QAgBkB,cAA3BR,iBAAiBG,QACxBX,SAASC,eAAe,sBAAsBc,MAAMC,QAAU,GAC9DhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,oBAAoBc,MAAMC,QApBlC,OAqBhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QArBvC,OAsBhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAtBzC,cAyBdC,6CAAiBjB,SAClBkB,cAAc,+FADIC,sBAEjBC,QAAQ,SACVH,eAAgB,OACVI,KAAkC,YAA3Bb,iBAAiBG,SAC9BM,eAAeF,MAAMC,QAAUK,KAAO,GA9BtB,QA+BXA,KAAM,OACDC,wBAA0BL,eAAeC,cAAc,sCACzDI,yBAA2BA,wBAAwBC,UACnDD,wBAAwBC,SAAU,EAClCD,wBAAwBE,cAAc,IAAIC,MAAM,oBAMzD,CACHC,KAAM,WACFlB,iBAAiBmB,SAAW,WACxBf,0BAEJgB,OAAOC,iBAAiB,QAAQ,KAC5BjB,4BAEJA,0BAEJkB,oBAAqBlB,uBACrBF,WAAYA,WACZqB,mBAAoB,SAASC,UACzBvB,WAAWE,MAAQqB,SAAW,IAAM,KAExCC,mBAAoB,kBACTxB,WAAWE,QAjFF,GAsFtBuB,iBAAoB,eAClBC,sBACEC,eAAiBpC,SAASC,eAAe,mBAExC,CACHyB,KAAM,SAASW,WACXF,gBAAkBE,WAEtBC,kBAAmB,iBACTC,mBAAqBH,eAAeI,QAAQJ,eAAeK,eAAeC,YACzEP,gBAAgBQ,MAAKC,QAAUA,OAAOC,OAASN,sBAE1DO,QAAS,WACLV,eAAeW,UAAW,WA8pBZC,WACfA,KAAKC,YACRD,KAAKE,YAAYF,KAAKC,YA/pBlBE,CAAiBf,kBAdH,GAmBpBgB,0BAA6B,iBACzBC,sBAAwBrD,SAASC,eAAe,uBAChDqD,2BAA6BtD,SAASC,eAAe,qCACvDsD,4BACEC,SAAWxD,SAASG,kBAAkB,aAAa,GAAGQ,eAQnD8C,aAAaC,UACbH,uBAGLA,sBAAsBI,YAAYC,KAAKC,UAAUH,UAAWtD,yBAOvD0D,kBAAYC,+DAAU,GAC3BN,aAAa,CACTO,SAAS,EACTD,QAASA,mBAkBRE,qBACLrC,OAAOC,iBAAiB,WAAYqC,WAC5BA,MAAMC,SAAW/D,4BAGfgE,UAAYR,KAAKS,MAAMH,MAAMI,SAE/BC,MAAMC,QAAQJ,kBACdK,eAAeC,kBAAkBN,WACjCN,mBACAlC,OAAO+C,YAKPC,yBAAyBR,WACzBN,cACAlC,OAAO+C,QAYfE,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN,+BACPC,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBrB,QAASoB,EAAE,GACXE,KAAM,YAEXC,KAAKP,aAAaQ,cAnBnB,MAAOC,mBA5Bb/B,aAAa,CACTO,SAAS,EACTD,+DAHuB,KA8BnB0B,CAAYD,MAAMzB,aAEvB,YAyBE2B,eAASC,0EACRC,YAAcD,YAAc,MAAQlB,eAAeoB,iBACnDC,eAAiB5D,iBAAiBI,oBAAoByD,UACtDC,OAASC,aAAa7F,eAAgB0F,gBAEtCI,KAAOF,OACP,wCACOxC,SACT,cAAgB2C,mBAAmBL,gBACnC,gBAAkBM,eAAeC,sBACjC,WAAaF,mBAAmBvE,OAAO0E,SAASnC,QAChD,gBAAkByB,YAClB,cAAgBtF,UACdF,eAAAA,6BACOoD,SACT,cAAgB2C,mBAAmBL,gBACnC,gBAAkBM,eAAeC,sBACjC,WAAaF,mBAAmBvE,OAAO0E,SAASnC,QAChD,WAAa9D,eACb,gBAAkBuF,YANhBxF,sCAUFuF,mBACOO,MAAQF,OAAS,oBAAsB,2BAE5CO,UAAY9B,eAAe+B,gCAC1BD,UAAYL,KAAO,cAAgBK,UAAYL,cAYjDD,aAAaQ,mBAAoBC,0BAC/B,IAAIC,IAAIF,oBAAoBtC,SAAW,IAAIwC,IAAID,mBAAmBvC,aAGtE,CACHzC,KAAM,WACF2B,sBAAsBuD,QAAU,WAC5BrD,sBAAwB3B,OAAOiF,KAAKnB,WAAY,WAGpD9D,OAAOkF,QAAU,WACbhD,eAGJlC,OAAOC,iBAAiB,gBAAgB,WACpCiC,iBACD,GAEHG,qBAEAX,2BAA2BsD,QAAU,SAASG,GAC1CA,EAAEC,iBACFzD,sBAAwB3B,OAAOiF,KAAKnB,UAAS,GAAO,SAAU,oCAGtE5C,QAAS,WACLO,sBAAsBN,UAAW,IA5JV,YA0K1B6B,yBAAyBqC,sCACxBjF,UAAgC,IAArBiF,QAAQjF,SACnBkF,qCAAYD,QAAQC,2DAAa,KACvCC,iBAAiBC,UAAUH,QAAQI,oBACnCjB,eAAekB,YAAYL,QAAQM,UACnC9C,eAAe+C,aAAaP,QAAQQ,KAAMR,QAAQM,SAAUN,QAAQpE,MACpE4B,eAAeiD,YAAY1F,UAC3B2F,oBAAoBC,aAAaV,iBAG/BC,iBAAoB,iBAChBU,eAAiB7H,SAASC,eAAe,mBACzC6H,eAAiB9H,SAASG,kBAAkB,oBAAoB,YAgB7D4H,mDACCC,eAAiBb,iBAAiBc,oBAClCC,iBAAmB9B,eAAeC,sBACnC2B,gBAAmBE,mBAGxBL,eAAelH,oCAAQqH,eAAenF,KACjCF,MAAKwF,aAAeA,YAAYZ,WAAaW,2DAD3BE,sBAC8CzH,aAGlE,CACHe,KAAM,WACFqG,oBAEJE,kBAAmB,kBACC/F,iBAAiBI,oBAAoB+F,QACtC1F,MAAK2F,QAAUA,OAAOC,aAAeT,eAAenH,SAEvEyG,UAAW,SAASoB,gBA1BMD,WAAAA,WA2BDC,WA1BzBV,eAAenH,MAAQ4H,WACvBR,qBAZkB,GA0CpB3B,eAAkB,iBACdqC,aAAezI,SAASC,eAAe,qBACtC,CACHoG,oBAAqB,kBACVoC,aAAa9H,OAExB2G,YAAa,SAASoB,MAClBD,aAAa9H,MAAQ+H,OAPT,GAYlBjE,eAAkB,iBACdkE,mBAAqB3I,SAASG,kBAAkB,WAAW,GAC3DyI,SAAW5I,SAASC,eAAe,WACnC4I,mBAAqB7I,SAASC,eAAe,oCAc1C6I,yBAAyBC,eAC9BF,mBAAmBlI,MAAQoI,uBAQtBC,cAAcvB,KAAMF,gBACnBwB,uBAWYtB,KAAMF,iBACjBE,KAnCuB,SAmCYF,SAZpB0B,CAAaxB,KAAMF,UACzCoB,mBAAmBhI,MAAQoI,cAC3BD,yBAAyBC,wBAwCpBrE,kBAAkBwE,aACjBC,WAAanJ,SAASG,kBAAkB,qBAAqB,GAC7DiJ,QAAUpJ,SAASC,eAAe,gCACpCkJ,aACAA,WAAWxI,MAAQiD,KAAKC,UAAUqF,QAElCE,QAAS,OACHC,cAAgBH,MAAMI,KAAIC,aACtBC,aAAexJ,SAASyJ,cAAc,aAC5CD,aAAaE,YAAcH,KAAK1G,KACzB2G,gBAEXJ,QAAQO,UAAY,SACdC,eAAiB5J,SAASyJ,cAAc,OACxCI,SAAW7J,SAASyJ,cAAc,MACxC5E,QAAQ,CAAC,aAAa,SAASiF,KAC3BA,IAAIC,WAAW,6BAA8B,YAAab,MAAMc,QAC3DC,MAAK,SAASC,OACXN,eAAeF,YAAcQ,YAGzCL,SAAS9I,MAAMoJ,OAAS,kBACxBd,cAAce,SAAQZ,cAAgBK,SAASQ,YAAYb,gBAC3DJ,QAAQiB,YAAYT,gBACpBR,QAAQiB,YAAYR,UACpBT,QAAQrI,MAAMC,QAAU,cAEtBsJ,UAAYtK,SAASC,eAAe,WAC1CqK,UAAUvH,UAAW,EACrBuH,UAAU3J,MAAQ,GAClB2J,UAAUxJ,gBAAgB,kBACpByJ,gBAAkBvK,SAASC,eAAe,2BAC5CsK,kBAAmBA,gBAAgB5J,MAAQ,UACzCkH,eAAiB7H,SAASC,eAAe,mBAC3C4H,iBAAkBA,eAAelH,MAAQ,UACvC6J,mBAAqBxK,SAASC,eAAe,iBAC/CuK,oBACAA,mBAAmBC,iBAAiB,gDAC/BL,SAAQM,oBAAuBA,kBAAkB3J,MAAMC,QAAU,gBAEpE2J,eAAiB3K,SAASkB,cAAc,0BAC1CyJ,iBACAA,eAAe5J,MAAMC,QAAU,cA4EhC,CACHU,KAAM,WACFoH,yBAAyBH,mBAAmBhI,QAEhD6G,aAAc,SAASC,KAAMF,SAAU1E,YAC7BsG,WAAanJ,SAASG,kBAAkB,qBAAqB,GAC/DgJ,aACAA,WAAWxI,MAAQ,UAEjByI,QAAUpJ,SAASC,eAAe,6BACpCmJ,UACAA,QAAQrI,MAAMC,QAAU,OACxBoI,QAAQO,UAAY,UAElBW,UAAYtK,SAASC,eAAe,WACtCqK,YACAA,UAAUvH,UAAW,EACrBuH,UAAUzJ,aAAa,WAAY,mBAEjC2J,mBAAqBxK,SAASC,eAAe,iBAC/CuK,oBACAA,mBAAmBC,iBAAiB,gDAC/BL,SAAQM,oBAAuBA,kBAAkB3J,MAAMC,QAAU,YAEpE2J,eAAiB3K,SAASkB,cAAc,0BAC1CyJ,iBACAA,eAAe5J,MAAMC,QAAU,IAEnCgI,cAAcvB,KAAMF,mBA7MR1E,MAChB+F,SAASjI,MAAQkC,KA6Mb+H,CAAW/H,OAEf6E,YAAa,SAAS1F,UAClBzB,mBAAmBwB,mBAAmBC,2BAjKpCe,SAAWxC,mBAAmBG,aACpCV,SAASC,eAAe,aAAa8C,SAAWA,SAChD/C,SAASC,eAAe,gBAAgB8C,SAAWA,SACnD/C,SAASC,eAAe,eAAe8C,SAAWA,SAClDxC,mBAAmBuB,sBA8Jf+I,IAEJhF,eAAgB,iBACN7D,SAAWzB,mBAAmB0B,2BACnB,MAAbD,SACO,SACa,MAAbA,SACA,WAEJ,OAEXwE,uBAAwB,kBAxLJiB,KAyLMkB,mBAAmBhI,OAxLpCmK,SA5CqB,UA6CnBrD,KAAKsD,MA7Cc,UA6CmB,GAE1CtD,SAJaA,MA2LpB/C,kBAAmBA,kBACnBsG,cAAe,iBACL7B,WAAanJ,SAASG,kBAAkB,qBAAqB,UAC5DgJ,cAAgBA,WAAWxI,OAEtCsK,4DAvFM9B,WAAanJ,SAASG,kBAAkB,qBAAqB,GAC7D+K,uCAAWlL,SAASG,kBAAkB,UAAU,2CAArCgL,sBAAyCxK,MACpDyK,QAAUC,SAAS,IAAIC,gBAAgB1J,OAAO0E,SAASiF,QAAQC,IAAI,YAAc,GACjFC,aAAezL,SAASC,eAAe,mBACvCyL,KAAOD,cAAgBA,aAAarK,QAAQ,QAC5C8H,MAAQtF,KAAKS,MAAM8E,WAAWxI,OAE9BgL,cAAgBzC,MAAMI,KAAIC,OAC5B3E,yBAAyB2E,eAlCJmC,YACnBE,eAAiBrH,MAAMsH,KAAKH,KAAKjB,iBAAiB,cACxDmB,eAAexB,SAAQ0B,QAAWA,MAAM/I,UAAW,eAEzCgJ,KAAO,CAAC,UAAW,kCAClBxH,MAAMsH,KAAK,IAAIG,SAASN,OAC1BO,QAAOC,WAAEC,iBAAUJ,KAAKjB,SAASqB,QACjC7C,KAAI8C,YAAED,IAAKxL,oBAAWwF,mBAAmBgG,KAAO,IAAMhG,mBAAmBxF,UACzE0L,KAAK,aAEVT,eAAexB,SAAQ0B,QAAWA,MAAM/I,UAAW,MAyB5CuJ,CAAoBZ,SAK/BhH,kBAAkBwE,OAElBrE,QAAQ,CAAC,YAAa,sBAAsB,SAAS0H,KAAMC,cACvDD,KAAKE,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CACFC,UAAWvB,SAAS/K,WACpB8K,QAASA,QACTyB,cAAelB,kBAEnB,GAAGzG,MAAK,WACRtD,OAAO0E,SAASwG,KAAOC,EAAEC,IAAIC,QAAU,uBAAyB/B,YACjE5F,MAAK,SAASE,OACbgH,aAAapH,gBAAgB,CACzBrB,QAASyB,MAAMzB,QACfsB,KAAM,kBArLF,GAoPlB6H,wBAA2B,iBACvBC,wBAA0BnN,SAASG,kBAAkB,6BACrDiN,uBAAyBpN,SAASG,kBAAkB,kCAAkC,OACxFkN,iBAAmB,SACjBC,oBAAsBtN,SAASG,kBAAkB,yBACjDoN,cAAgBvN,SAASG,kBAAkB,wBAAwB,OACrEqN,gBAAkB,SAChBC,cAAgBzN,SAASG,kBAAkB,qCA4CxCuN,gCACLP,wBAAwB/C,SAAQ,SAASuD,UACrCA,SAAShM,SAAW,WACXgM,SAASpM,QAGV8L,iBAAiBO,KAAKD,SAAShN,OAF/B0M,iBAAmBA,iBAAiBpB,QAAOjJ,MAAQA,OAAS2K,SAAShN,QAIzEyM,uBAAuBzM,MAAQiD,KAAKC,UAAUwJ,mCAlBhDQ,gBAAkBtJ,MAAMsH,KAAKsB,yBAC9BW,MAAKH,UAA+B,YAAnBA,SAAShN,OAAuBgN,SAASpM,UAC/DvB,SAASyK,iBAAiB,kDAAkDL,SAAQ,SAASpH,MACzFA,KAAKjC,MAAMC,QAAU6M,gBAAkB,GAAK,UAgBxCE,aA+BL,CACHrM,KAAM,WAnEN4L,oBAAoBlD,SAAQ,SAASuD,UACjCA,SAAShM,SAAW,WACXgM,SAASpM,QAGViM,gBAAgBI,KAAKD,SAAShN,OAF9B6M,gBAAkBA,gBAAgBvB,QAAOjJ,MAAQA,OAAS2K,SAAShN,QAIvE4M,cAAc5M,MAAQiD,KAAKC,UAAU2J,qBA8DzCE,gCAzBJD,cAAcrD,SAAQ,SAAS4D,iBAC3BA,gBAAgBrM,SAAW,WAClBqM,gBAAgBzM,QAQjB+L,oBAAoBlD,SAAQ,SAAS6D,kBAhE5BC,MAAOC,QAiERF,aAAaG,aAAa,aAAeJ,gBAAgBrN,QACzDsN,aAAa1M,SAAU,EAlEtB2M,MAmEeV,gBAnERW,QAmEyBF,aAAatN,MAlE7DuN,MAAMpD,SAASqD,UAChBD,MAAMN,KAAKO,aAuDHb,oBAAoBlD,SAAQ,SAAS6D,cAC7BA,aAAaG,aAAa,aAAeJ,gBAAgBrN,QACzDsN,aAAa1M,SAAU,EACvBiM,gBAAkBA,gBAAgBvB,QAAOjJ,MAAQiL,aAAatN,QAAUqC,WAWpFuK,cAAc5M,MAAQiD,KAAKC,UAAU2J,uBAtFpB,GAoG3B7F,oBAAuB,iBACnB0G,iBAAmBrO,SAASC,eAAe,4BAC1C,CACH2H,aAAc,SAASV,WACfA,UACAmH,iBAAiBxN,aAAa,QAAS+C,KAAKC,UAAUqD,YAEtDmH,iBAAiBvN,gBAAgB,WAPpB,YAiBpBwN,qBAAqBC,UAC1B1J,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACNuJ,SACPtJ,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBrB,QAASoB,EAAE,GAAK,MAAQjF,cAAckO,aAAa,SAAW,OAC9D/I,KAAM,eAEXC,KAAKP,aAAaQ,cAEzBrD,iBAAiBY,UACjBM,0BAA0BN,gBAGvB,CACHpB,KAAM,SAAS8M,eAAgBC,eAAgB/F,MAC3CtI,eAAiBqO,eACjBpO,eAAiBqI,KACjBpI,UAAYkO,qBACNE,OAAS1O,SAASC,eAAe,WAAWmO,aAAa,SACzDjM,gBAAkByB,KAAKS,MAAMrE,SAASG,kBAAkB,0BAA0B,GAAGQ,OACvF+N,QAyD+E,KAAhF1O,SAASG,kBAAkB,wBAAwB,GAAGiO,aAAa,SAxDlEE,qBAAqB,6BACbnM,gBAAgB6H,QAGxB9H,iBAAiBR,KAAKS,iBACtBgF,iBAAiBzF,OACjB+C,eAAe/C,OACfwL,wBAAwBxL,OACxB0B,0BAA0B1B,OAC1BnB,mBAAmBmB,QAPnB4M,qBAAqB,6BASrBvO,iBACA8E,QAAQ,CAAC,mCAAmC,SAAS8J,aACjDA,YAAYjN,KAAK3B,gBAAiBO,oBAIpCmL,aAAezL,SAASC,eAAe,mBACvCyL,KAAOD,cAAgBA,aAAarK,QAAQ,WAC9CsK,KAAM,KACFkD,eAAgB,QACdC,aAAe7O,SAASC,eAAe,aACzC4O,cACAA,aAAahN,iBAAiB,SAAS,WACnC+M,eAAgB,KAGxBlD,KAAK7J,iBAAiB,UAAU,SAASkF,GACjC6H,cACAA,eAAgB,EAGhBnK,eAAeuG,kBACfjE,EAAEC,iBACFvC,eAAewG"} \ No newline at end of file diff --git a/amd/src/mod_form.js b/amd/src/mod_form.js index 81eb15fa..22b959da 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -494,7 +494,8 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv * an independent single-task submission, so picker-payload → form-field * mapping lives in applyPickerPayloadToForm and is shared with the * single-task path. Validation runs server-side via the shared form - * pipeline; errors surface via Notification.exception. + * pipeline; errors surface as a top-of-page notification with the + * validator's localized message. */ function submitMultiTasks() { const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; @@ -523,7 +524,12 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }, }])[0].done(function() { window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; - }).fail(Notification.exception); + }).fail(function(error) { + Notification.addNotification({ + message: error.message, + type: 'error', + }); + }); }); } diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 2d6bb37d..8b154272 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -127,7 +127,7 @@ $string['mumie_grade_percentage'] = 'Bewerung in %'; $string['mumie_grading_settings'] = "Individuelle Bewertungseinstellungen"; $string['mumie_multi_problem_selector'] = 'Alternativ können Sie mit der Mehrfach-Aufgabenauswahl auch mehrere MUMIE-Aufgaben auf einmal auswählen. Alle Aufgaben werden mit den eingestellten Einstellungen angelegt (Punkte, Frist, Startcontainer etc.). Jede Aufgabe behält ihren eigenen Namen — anders als bei der Einzelauswahl kann kein eigener Name vergeben werden.

Weitere Informationen finden Sie in unserem Wiki'; -$string['mumie_multi_task_validation_error'] = 'Validierungsfehler: {$a}'; +$string['mumie_multi_task_validation_error'] = '{$a}'; $string['mumie_multi_tasks_selected'] = 'Sie haben folgende {$a} Aufgaben ausgewählt:'; $string['mumie_no_other_task_found'] = 'Keine andere MUMIE Tasks in Kurs gefunden'; $string['mumie_no_submissions'] = 'Keine Antworten abgegeben'; diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 062b3e38..4edd0442 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -122,7 +122,7 @@ $string['mumie_grade_percentage'] = 'Grade in %'; $string['mumie_grading_settings'] = "Individual grading settings"; $string['mumie_multi_problem_selector'] = 'Alternatively, you can also create multiple MUMIE Tasks at once using the Multi Problem Selector. All tasks will be created with the settings configured (points, deadline, container type, etc.). Each task keeps its own name — unlike single task creation, no custom name can be assigned.

For more information, have a look at our wiki'; -$string['mumie_multi_task_validation_error'] = 'Validation error: {$a}'; +$string['mumie_multi_task_validation_error'] = '{$a}'; $string['mumie_multi_tasks_selected'] = 'You have selected the following {$a} problems:'; $string['mumie_no_other_task_found'] = 'No other MUMIE Tasks found in course'; $string['mumie_no_submissions'] = 'No answers submitted'; From 34a4a571324cbd26c3fbf9e2a662c3b2e0b8f256 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 12:46:00 +0200 Subject: [PATCH 080/101] Rework Error message into modal. --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 9 +++------ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 18960637..11babc5b 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){Notification.addNotification({message:error.message,type:"error"})}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){Notification.alert(error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 550b7a75..1ea76180 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a top-of-page notification with the\n * validator's localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n Notification.addNotification({\n message: error.message,\n type: 'error',\n });\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n Notification.alert(error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 22b959da..bbe70d93 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -494,8 +494,8 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv * an independent single-task submission, so picker-payload → form-field * mapping lives in applyPickerPayloadToForm and is shared with the * single-task path. Validation runs server-side via the shared form - * pipeline; errors surface as a top-of-page notification with the - * validator's localized message. + * pipeline; errors surface as a modal alert with the validator's + * localized message. */ function submitMultiTasks() { const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; @@ -525,10 +525,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }])[0].done(function() { window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; }).fail(function(error) { - Notification.addNotification({ - message: error.message, - type: 'error', - }); + Notification.alert(error.message); }); }); } From 41e0a7858adf39fde610ac1eb5f3d01c2d0552bb Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 12:54:04 +0200 Subject: [PATCH 081/101] Rework Error message into modal. --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 11babc5b..221a6193 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){Notification.alert(error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){Notification.exception({message:error.message})}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 1ea76180..133438d4 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n Notification.alert(error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n Notification.exception({message: error.message});\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 bbe70d93..8223efd3 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -525,7 +525,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }])[0].done(function() { window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; }).fail(function(error) { - Notification.alert(error.message); + Notification.exception({message: error.message}); }); }); } From ae6b5ea6ff44d0a5e9d842ec14142fc133e8395b Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 12:58:58 +0200 Subject: [PATCH 082/101] Rework Error message. --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 221a6193..be59b7c2 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){Notification.exception({message:error.message})}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){Notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 133438d4..084c1422 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n Notification.exception({message: error.message});\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"mappings":"AAAAA,4BAAO,CAAC,SAAU,iBAAkB,qBAAsB,iCAAkC,cACxF,iBACUC,gBAAkBC,SAASC,eAAe,wBAC1CC,cAAgBF,SAASG,kBAAkB,wBAAwB,OACrEC,eACAC,eACAC,gBAGEC,mBAAsB,iBAElBC,iBAAmBR,SAASC,eAAe,wBAC3CQ,WAAaT,SAASC,eAAe,8BAKlCS,mBACuB,MAArBD,WAAWE,eAMbC,mDACYF,cAEbF,iBAAiBK,aAAa,WAAY,YAC1CL,iBAAiBG,MAAQ,aAEzBH,iBAAiBM,gBAAgB,YAKN,cAA3BN,iBAAiBG,OACjBX,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,sBAAsBc,MAAMC,QALpC,OAMhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QANzC,OAOhBhB,SAASC,eAAe,oBAAoBc,MAAMC,QAPlC,OAQhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QARvC,QASkB,YAA3BR,iBAAiBG,OACxBX,SAASC,eAAe,oBAAoBc,MAAMC,QAAU,GAC5DhB,SAASC,eAAe,yBAAyBc,MAAMC,QAAU,GAEjEhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAbzC,OAchBhB,SAASC,eAAe,sBAAsBc,MAAMC,QAdpC,OAehBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAfzC,QAgBkB,cAA3BR,iBAAiBG,QACxBX,SAASC,eAAe,sBAAsBc,MAAMC,QAAU,GAC9DhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAAU,GAEnEhB,SAASC,eAAe,oBAAoBc,MAAMC,QApBlC,OAqBhBhB,SAASC,eAAe,yBAAyBc,MAAMC,QArBvC,OAsBhBhB,SAASC,eAAe,2BAA2Bc,MAAMC,QAtBzC,cAyBdC,6CAAiBjB,SAClBkB,cAAc,+FADIC,sBAEjBC,QAAQ,SACVH,eAAgB,OACVI,KAAkC,YAA3Bb,iBAAiBG,SAC9BM,eAAeF,MAAMC,QAAUK,KAAO,GA9BtB,QA+BXA,KAAM,OACDC,wBAA0BL,eAAeC,cAAc,sCACzDI,yBAA2BA,wBAAwBC,UACnDD,wBAAwBC,SAAU,EAClCD,wBAAwBE,cAAc,IAAIC,MAAM,oBAMzD,CACHC,KAAM,WACFlB,iBAAiBmB,SAAW,WACxBf,0BAEJgB,OAAOC,iBAAiB,QAAQ,KAC5BjB,4BAEJA,0BAEJkB,oBAAqBlB,uBACrBF,WAAYA,WACZqB,mBAAoB,SAASC,UACzBvB,WAAWE,MAAQqB,SAAW,IAAM,KAExCC,mBAAoB,kBACTxB,WAAWE,QAjFF,GAsFtBuB,iBAAoB,eAClBC,sBACEC,eAAiBpC,SAASC,eAAe,mBAExC,CACHyB,KAAM,SAASW,WACXF,gBAAkBE,WAEtBC,kBAAmB,iBACTC,mBAAqBH,eAAeI,QAAQJ,eAAeK,eAAeC,YACzEP,gBAAgBQ,MAAKC,QAAUA,OAAOC,OAASN,sBAE1DO,QAAS,WACLV,eAAeW,UAAW,WA2pBZC,WACfA,KAAKC,YACRD,KAAKE,YAAYF,KAAKC,YA5pBlBE,CAAiBf,kBAdH,GAmBpBgB,0BAA6B,iBACzBC,sBAAwBrD,SAASC,eAAe,uBAChDqD,2BAA6BtD,SAASC,eAAe,qCACvDsD,4BACEC,SAAWxD,SAASG,kBAAkB,aAAa,GAAGQ,eAQnD8C,aAAaC,UACbH,uBAGLA,sBAAsBI,YAAYC,KAAKC,UAAUH,UAAWtD,yBAOvD0D,kBAAYC,+DAAU,GAC3BN,aAAa,CACTO,SAAS,EACTD,QAASA,mBAkBRE,qBACLrC,OAAOC,iBAAiB,WAAYqC,WAC5BA,MAAMC,SAAW/D,4BAGfgE,UAAYR,KAAKS,MAAMH,MAAMI,SAE/BC,MAAMC,QAAQJ,kBACdK,eAAeC,kBAAkBN,WACjCN,mBACAlC,OAAO+C,YAKPC,yBAAyBR,WACzBN,cACAlC,OAAO+C,QAYfE,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACN,+BACPC,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBrB,QAASoB,EAAE,GACXE,KAAM,YAEXC,KAAKP,aAAaQ,cAnBnB,MAAOC,mBA5Bb/B,aAAa,CACTO,SAAS,EACTD,+DAHuB,KA8BnB0B,CAAYD,MAAMzB,aAEvB,YAyBE2B,eAASC,0EACRC,YAAcD,YAAc,MAAQlB,eAAeoB,iBACnDC,eAAiB5D,iBAAiBI,oBAAoByD,UACtDC,OAASC,aAAa7F,eAAgB0F,gBAEtCI,KAAOF,OACP,wCACOxC,SACT,cAAgB2C,mBAAmBL,gBACnC,gBAAkBM,eAAeC,sBACjC,WAAaF,mBAAmBvE,OAAO0E,SAASnC,QAChD,gBAAkByB,YAClB,cAAgBtF,UACdF,eAAAA,6BACOoD,SACT,cAAgB2C,mBAAmBL,gBACnC,gBAAkBM,eAAeC,sBACjC,WAAaF,mBAAmBvE,OAAO0E,SAASnC,QAChD,WAAa9D,eACb,gBAAkBuF,YANhBxF,sCAUFuF,mBACOO,MAAQF,OAAS,oBAAsB,2BAE5CO,UAAY9B,eAAe+B,gCAC1BD,UAAYL,KAAO,cAAgBK,UAAYL,cAYjDD,aAAaQ,mBAAoBC,0BAC/B,IAAIC,IAAIF,oBAAoBtC,SAAW,IAAIwC,IAAID,mBAAmBvC,aAGtE,CACHzC,KAAM,WACF2B,sBAAsBuD,QAAU,WAC5BrD,sBAAwB3B,OAAOiF,KAAKnB,WAAY,WAGpD9D,OAAOkF,QAAU,WACbhD,eAGJlC,OAAOC,iBAAiB,gBAAgB,WACpCiC,iBACD,GAEHG,qBAEAX,2BAA2BsD,QAAU,SAASG,GAC1CA,EAAEC,iBACFzD,sBAAwB3B,OAAOiF,KAAKnB,UAAS,GAAO,SAAU,oCAGtE5C,QAAS,WACLO,sBAAsBN,UAAW,IA5JV,YA0K1B6B,yBAAyBqC,sCACxBjF,UAAgC,IAArBiF,QAAQjF,SACnBkF,qCAAYD,QAAQC,2DAAa,KACvCC,iBAAiBC,UAAUH,QAAQI,oBACnCjB,eAAekB,YAAYL,QAAQM,UACnC9C,eAAe+C,aAAaP,QAAQQ,KAAMR,QAAQM,SAAUN,QAAQpE,MACpE4B,eAAeiD,YAAY1F,UAC3B2F,oBAAoBC,aAAaV,iBAG/BC,iBAAoB,iBAChBU,eAAiB7H,SAASC,eAAe,mBACzC6H,eAAiB9H,SAASG,kBAAkB,oBAAoB,YAgB7D4H,mDACCC,eAAiBb,iBAAiBc,oBAClCC,iBAAmB9B,eAAeC,sBACnC2B,gBAAmBE,mBAGxBL,eAAelH,oCAAQqH,eAAenF,KACjCF,MAAKwF,aAAeA,YAAYZ,WAAaW,2DAD3BE,sBAC8CzH,aAGlE,CACHe,KAAM,WACFqG,oBAEJE,kBAAmB,kBACC/F,iBAAiBI,oBAAoB+F,QACtC1F,MAAK2F,QAAUA,OAAOC,aAAeT,eAAenH,SAEvEyG,UAAW,SAASoB,gBA1BMD,WAAAA,WA2BDC,WA1BzBV,eAAenH,MAAQ4H,WACvBR,qBAZkB,GA0CpB3B,eAAkB,iBACdqC,aAAezI,SAASC,eAAe,qBACtC,CACHoG,oBAAqB,kBACVoC,aAAa9H,OAExB2G,YAAa,SAASoB,MAClBD,aAAa9H,MAAQ+H,OAPT,GAYlBjE,eAAkB,iBACdkE,mBAAqB3I,SAASG,kBAAkB,WAAW,GAC3DyI,SAAW5I,SAASC,eAAe,WACnC4I,mBAAqB7I,SAASC,eAAe,oCAc1C6I,yBAAyBC,eAC9BF,mBAAmBlI,MAAQoI,uBAQtBC,cAAcvB,KAAMF,gBACnBwB,uBAWYtB,KAAMF,iBACjBE,KAnCuB,SAmCYF,SAZpB0B,CAAaxB,KAAMF,UACzCoB,mBAAmBhI,MAAQoI,cAC3BD,yBAAyBC,wBAwCpBrE,kBAAkBwE,aACjBC,WAAanJ,SAASG,kBAAkB,qBAAqB,GAC7DiJ,QAAUpJ,SAASC,eAAe,gCACpCkJ,aACAA,WAAWxI,MAAQiD,KAAKC,UAAUqF,QAElCE,QAAS,OACHC,cAAgBH,MAAMI,KAAIC,aACtBC,aAAexJ,SAASyJ,cAAc,aAC5CD,aAAaE,YAAcH,KAAK1G,KACzB2G,gBAEXJ,QAAQO,UAAY,SACdC,eAAiB5J,SAASyJ,cAAc,OACxCI,SAAW7J,SAASyJ,cAAc,MACxC5E,QAAQ,CAAC,aAAa,SAASiF,KAC3BA,IAAIC,WAAW,6BAA8B,YAAab,MAAMc,QAC3DC,MAAK,SAASC,OACXN,eAAeF,YAAcQ,YAGzCL,SAAS9I,MAAMoJ,OAAS,kBACxBd,cAAce,SAAQZ,cAAgBK,SAASQ,YAAYb,gBAC3DJ,QAAQiB,YAAYT,gBACpBR,QAAQiB,YAAYR,UACpBT,QAAQrI,MAAMC,QAAU,cAEtBsJ,UAAYtK,SAASC,eAAe,WAC1CqK,UAAUvH,UAAW,EACrBuH,UAAU3J,MAAQ,GAClB2J,UAAUxJ,gBAAgB,kBACpByJ,gBAAkBvK,SAASC,eAAe,2BAC5CsK,kBAAmBA,gBAAgB5J,MAAQ,UACzCkH,eAAiB7H,SAASC,eAAe,mBAC3C4H,iBAAkBA,eAAelH,MAAQ,UACvC6J,mBAAqBxK,SAASC,eAAe,iBAC/CuK,oBACAA,mBAAmBC,iBAAiB,gDAC/BL,SAAQM,oBAAuBA,kBAAkB3J,MAAMC,QAAU,gBAEpE2J,eAAiB3K,SAASkB,cAAc,0BAC1CyJ,iBACAA,eAAe5J,MAAMC,QAAU,cAyEhC,CACHU,KAAM,WACFoH,yBAAyBH,mBAAmBhI,QAEhD6G,aAAc,SAASC,KAAMF,SAAU1E,YAC7BsG,WAAanJ,SAASG,kBAAkB,qBAAqB,GAC/DgJ,aACAA,WAAWxI,MAAQ,UAEjByI,QAAUpJ,SAASC,eAAe,6BACpCmJ,UACAA,QAAQrI,MAAMC,QAAU,OACxBoI,QAAQO,UAAY,UAElBW,UAAYtK,SAASC,eAAe,WACtCqK,YACAA,UAAUvH,UAAW,EACrBuH,UAAUzJ,aAAa,WAAY,mBAEjC2J,mBAAqBxK,SAASC,eAAe,iBAC/CuK,oBACAA,mBAAmBC,iBAAiB,gDAC/BL,SAAQM,oBAAuBA,kBAAkB3J,MAAMC,QAAU,YAEpE2J,eAAiB3K,SAASkB,cAAc,0BAC1CyJ,iBACAA,eAAe5J,MAAMC,QAAU,IAEnCgI,cAAcvB,KAAMF,mBA1MR1E,MAChB+F,SAASjI,MAAQkC,KA0Mb+H,CAAW/H,OAEf6E,YAAa,SAAS1F,UAClBzB,mBAAmBwB,mBAAmBC,2BA9JpCe,SAAWxC,mBAAmBG,aACpCV,SAASC,eAAe,aAAa8C,SAAWA,SAChD/C,SAASC,eAAe,gBAAgB8C,SAAWA,SACnD/C,SAASC,eAAe,eAAe8C,SAAWA,SAClDxC,mBAAmBuB,sBA2Jf+I,IAEJhF,eAAgB,iBACN7D,SAAWzB,mBAAmB0B,2BACnB,MAAbD,SACO,SACa,MAAbA,SACA,WAEJ,OAEXwE,uBAAwB,kBArLJiB,KAsLMkB,mBAAmBhI,OArLpCmK,SA5CqB,UA6CnBrD,KAAKsD,MA7Cc,UA6CmB,GAE1CtD,SAJaA,MAwLpB/C,kBAAmBA,kBACnBsG,cAAe,iBACL7B,WAAanJ,SAASG,kBAAkB,qBAAqB,UAC5DgJ,cAAgBA,WAAWxI,OAEtCsK,4DApFM9B,WAAanJ,SAASG,kBAAkB,qBAAqB,GAC7D+K,uCAAWlL,SAASG,kBAAkB,UAAU,2CAArCgL,sBAAyCxK,MACpDyK,QAAUC,SAAS,IAAIC,gBAAgB1J,OAAO0E,SAASiF,QAAQC,IAAI,YAAc,GACjFC,aAAezL,SAASC,eAAe,mBACvCyL,KAAOD,cAAgBA,aAAarK,QAAQ,QAC5C8H,MAAQtF,KAAKS,MAAM8E,WAAWxI,OAE9BgL,cAAgBzC,MAAMI,KAAIC,OAC5B3E,yBAAyB2E,eAlCJmC,YACnBE,eAAiBrH,MAAMsH,KAAKH,KAAKjB,iBAAiB,cACxDmB,eAAexB,SAAQ0B,QAAWA,MAAM/I,UAAW,eAEzCgJ,KAAO,CAAC,UAAW,kCAClBxH,MAAMsH,KAAK,IAAIG,SAASN,OAC1BO,QAAOC,WAAEC,iBAAUJ,KAAKjB,SAASqB,QACjC7C,KAAI8C,YAAED,IAAKxL,oBAAWwF,mBAAmBgG,KAAO,IAAMhG,mBAAmBxF,UACzE0L,KAAK,aAEVT,eAAexB,SAAQ0B,QAAWA,MAAM/I,UAAW,MAyB5CuJ,CAAoBZ,SAK/BhH,kBAAkBwE,OAElBrE,QAAQ,CAAC,YAAa,sBAAsB,SAAS0H,KAAMC,cACvDD,KAAKE,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CACFC,UAAWvB,SAAS/K,WACpB8K,QAASA,QACTyB,cAAelB,kBAEnB,GAAGzG,MAAK,WACRtD,OAAO0E,SAASwG,KAAOC,EAAEC,IAAIC,QAAU,uBAAyB/B,YACjE5F,MAAK,SAASE,OACbgH,aAAajH,UAAU,CAACxB,QAASyB,MAAMzB,kBAnL/B,GAiPlBmJ,wBAA2B,iBACvBC,wBAA0BnN,SAASG,kBAAkB,6BACrDiN,uBAAyBpN,SAASG,kBAAkB,kCAAkC,OACxFkN,iBAAmB,SACjBC,oBAAsBtN,SAASG,kBAAkB,yBACjDoN,cAAgBvN,SAASG,kBAAkB,wBAAwB,OACrEqN,gBAAkB,SAChBC,cAAgBzN,SAASG,kBAAkB,qCA4CxCuN,gCACLP,wBAAwB/C,SAAQ,SAASuD,UACrCA,SAAShM,SAAW,WACXgM,SAASpM,QAGV8L,iBAAiBO,KAAKD,SAAShN,OAF/B0M,iBAAmBA,iBAAiBpB,QAAOjJ,MAAQA,OAAS2K,SAAShN,QAIzEyM,uBAAuBzM,MAAQiD,KAAKC,UAAUwJ,mCAlBhDQ,gBAAkBtJ,MAAMsH,KAAKsB,yBAC9BW,MAAKH,UAA+B,YAAnBA,SAAShN,OAAuBgN,SAASpM,UAC/DvB,SAASyK,iBAAiB,kDAAkDL,SAAQ,SAASpH,MACzFA,KAAKjC,MAAMC,QAAU6M,gBAAkB,GAAK,UAgBxCE,aA+BL,CACHrM,KAAM,WAnEN4L,oBAAoBlD,SAAQ,SAASuD,UACjCA,SAAShM,SAAW,WACXgM,SAASpM,QAGViM,gBAAgBI,KAAKD,SAAShN,OAF9B6M,gBAAkBA,gBAAgBvB,QAAOjJ,MAAQA,OAAS2K,SAAShN,QAIvE4M,cAAc5M,MAAQiD,KAAKC,UAAU2J,qBA8DzCE,gCAzBJD,cAAcrD,SAAQ,SAAS4D,iBAC3BA,gBAAgBrM,SAAW,WAClBqM,gBAAgBzM,QAQjB+L,oBAAoBlD,SAAQ,SAAS6D,kBAhE5BC,MAAOC,QAiERF,aAAaG,aAAa,aAAeJ,gBAAgBrN,QACzDsN,aAAa1M,SAAU,EAlEtB2M,MAmEeV,gBAnERW,QAmEyBF,aAAatN,MAlE7DuN,MAAMpD,SAASqD,UAChBD,MAAMN,KAAKO,aAuDHb,oBAAoBlD,SAAQ,SAAS6D,cAC7BA,aAAaG,aAAa,aAAeJ,gBAAgBrN,QACzDsN,aAAa1M,SAAU,EACvBiM,gBAAkBA,gBAAgBvB,QAAOjJ,MAAQiL,aAAatN,QAAUqC,WAWpFuK,cAAc5M,MAAQiD,KAAKC,UAAU2J,uBAtFpB,GAoG3B7F,oBAAuB,iBACnB0G,iBAAmBrO,SAASC,eAAe,4BAC1C,CACH2H,aAAc,SAASV,WACfA,UACAmH,iBAAiBxN,aAAa,QAAS+C,KAAKC,UAAUqD,YAEtDmH,iBAAiBvN,gBAAgB,WAPpB,YAiBpBwN,qBAAqBC,UAC1B1J,QAAQ,CAAC,WAAY,sBAAsB,SAASC,IAAKC,cACrDD,IAAIE,YAAY,CAAC,KACNuJ,SACPtJ,UAAW,eACXC,MAAK,SAASC,GACdJ,aAAaK,gBAAgB,CACzBrB,QAASoB,EAAE,GAAK,MAAQjF,cAAckO,aAAa,SAAW,OAC9D/I,KAAM,eAEXC,KAAKP,aAAaQ,cAEzBrD,iBAAiBY,UACjBM,0BAA0BN,gBAGvB,CACHpB,KAAM,SAAS8M,eAAgBC,eAAgB/F,MAC3CtI,eAAiBqO,eACjBpO,eAAiBqI,KACjBpI,UAAYkO,qBACNE,OAAS1O,SAASC,eAAe,WAAWmO,aAAa,SACzDjM,gBAAkByB,KAAKS,MAAMrE,SAASG,kBAAkB,0BAA0B,GAAGQ,OACvF+N,QAyD+E,KAAhF1O,SAASG,kBAAkB,wBAAwB,GAAGiO,aAAa,SAxDlEE,qBAAqB,6BACbnM,gBAAgB6H,QAGxB9H,iBAAiBR,KAAKS,iBACtBgF,iBAAiBzF,OACjB+C,eAAe/C,OACfwL,wBAAwBxL,OACxB0B,0BAA0B1B,OAC1BnB,mBAAmBmB,QAPnB4M,qBAAqB,6BASrBvO,iBACA8E,QAAQ,CAAC,mCAAmC,SAAS8J,aACjDA,YAAYjN,KAAK3B,gBAAiBO,oBAIpCmL,aAAezL,SAASC,eAAe,mBACvCyL,KAAOD,cAAgBA,aAAarK,QAAQ,WAC9CsK,KAAM,KACFkD,eAAgB,QACdC,aAAe7O,SAASC,eAAe,aACzC4O,cACAA,aAAahN,iBAAiB,SAAS,WACnC+M,eAAgB,KAGxBlD,KAAK7J,iBAAiB,UAAU,SAASkF,GACjC6H,cACAA,eAAgB,EAGhBnK,eAAeuG,kBACfjE,EAAEC,iBACFvC,eAAewG"} \ 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n Notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 8223efd3..8ccdfa57 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -525,7 +525,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }])[0].done(function() { window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; }).fail(function(error) { - Notification.exception({message: error.message}); + Notification.alert('', error.message); }); }); } From 9aaa23add66348cac4942d4c5a48374b1730c5dd Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Wed, 24 Jun 2026 14:20:31 +0200 Subject: [PATCH 083/101] rename Notification to notification to avoid global overwriting. --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index be59b7c2..2cd00f80 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,Notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){Notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 084c1422..124ebcb4 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, Notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n Notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","Notification","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 8ccdfa57..428bebb8 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -514,7 +514,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv // restore the multi-task UI so the form is coherent if the AJAX call fails. setMultiSelection(tasks); - require(['core/ajax', 'core/notification'], function(Ajax, Notification) { + require(['core/ajax', 'core/notification'], function(Ajax, notification) { Ajax.call([{ methodname: 'mod_mumie_create_multiple_mumie_tasks', args: { @@ -525,7 +525,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv }])[0].done(function() { window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId; }).fail(function(error) { - Notification.alert('', error.message); + notification.alert('', error.message); }); }); } From aa7927e867b2344cc5e6ea5a9b6ec85ef2f312d8 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Thu, 25 Jun 2026 13:54:04 +0200 Subject: [PATCH 084/101] Moved to clean_up_duration_values locallib.php --- externallib.php | 5 +++-- locallib.php | 18 ++++++++++++++++++ mod_form.php | 20 +------------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/externallib.php b/externallib.php index 694608d6..ee292272 100644 --- a/externallib.php +++ b/externallib.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die; +use mod_mumie\locallib; + require_once($CFG->libdir . "/externallib.php"); /** @@ -160,7 +162,6 @@ public static function create_multiple_mumie_tasks($contextid, $section, $tasksf require_once($CFG->dirroot . '/course/modlib.php'); require_once($CFG->dirroot . '/mod/mumie/lib.php'); require_once($CFG->dirroot . '/mod/mumie/locallib.php'); - require_once($CFG->dirroot . '/mod/mumie/mod_form.php'); require_once($CFG->dirroot . '/mod/mumie/forms/form_field_decoder.php'); require_once($CFG->dirroot . '/mod/mumie/forms/mumie_task_validator.php'); @@ -193,7 +194,7 @@ public static function create_multiple_mumie_tasks($contextid, $section, $tasksf parse_str($taskpost, $formfields); $instancedata = \mod_mumie\form_field_decoder::from_form_fields($formfields); - \mod_mumie_mod_form::clean_up_duration_values($instancedata); + locallib::clean_up_duration_values($instancedata); $instancedata->modulename = 'mumie'; $instancedata->module = $mumiemodule->id; diff --git a/locallib.php b/locallib.php index a7fa5938..fcfabdbe 100644 --- a/locallib.php +++ b/locallib.php @@ -256,4 +256,22 @@ public static function callbackimpl_before_standard_top_of_body_html(): string { return ""; } + + /** + * Zero the duration column that does not match duration_selector. + * + * The form exposes duedate and timelimit side by side with duration_selector choosing + * which one is active. This enforces the invariant "only the active column is non-zero" + * before the data is handed to the persistence layer. + * + * @param stdClass $data Submitted form data (mutated in place). + */ + public static function clean_up_duration_values(\stdClass $data): void { + if ($data->duration_selector !== 'duedate') { + $data->duedate = 0; + } + if ($data->duration_selector !== 'timelimit') { + $data->timelimit = 0; + } + } } diff --git a/mod_form.php b/mod_form.php index 9c116465..ad0c57ee 100644 --- a/mod_form.php +++ b/mod_form.php @@ -270,25 +270,7 @@ public function validation($data, $files): array { */ public function data_postprocessing($data): void { parent::data_postprocessing($data); - self::clean_up_duration_values($data); - } - - /** - * Zero the duration column that does not match duration_selector. - * - * The form exposes duedate and timelimit side by side with duration_selector choosing - * which one is active. This enforces the invariant "only the active column is non-zero" - * before the data is handed to the persistence layer. - * - * @param stdClass $data Submitted form data (mutated in place). - */ - public static function clean_up_duration_values(stdClass $data): void { - if ($data->duration_selector !== 'duedate') { - $data->duedate = 0; - } - if ($data->duration_selector !== 'timelimit') { - $data->timelimit = 0; - } + locallib::clean_up_duration_values($data); } /** From f04922f1a713b698e3f7e865ff1a6badbf5650b9 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Thu, 25 Jun 2026 14:22:49 +0200 Subject: [PATCH 085/101] Refactor addMessageListener: unify try/catch coverage --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 18 +++++++----------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 2cd00f80..9c113bf1 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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);if(Array.isArray(importObj))return taskController.setMultiSelection(importObj),sendSuccess(),void window.focus();try{applyPickerPayloadToForm(importObj),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)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 124ebcb4..8a2443bb 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n sendSuccess();\n window.focus();\n return;\n }\n\n try {\n applyPickerPayloadToForm(importObj);\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","focus","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 428bebb8..fcd4c25f 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -161,20 +161,16 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv if (event.origin !== lmsSelectorUrl) { return; } - const importObj = JSON.parse(event.data); - - if (Array.isArray(importObj)) { - taskController.setMultiSelection(importObj); - sendSuccess(); - window.focus(); - return; - } - try { - applyPickerPayloadToForm(importObj); + const importObj = JSON.parse(event.data); + if (Array.isArray(importObj)) { + taskController.setMultiSelection(importObj); + } else { + applyPickerPayloadToForm(importObj); + displayProblemSelectedMessage(); + } sendSuccess(); window.focus(); - displayProblemSelectedMessage(); } catch (error) { sendFailure(error.message); } From 2cb4317ca752a99627c660b51d81c170d15da29f Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Thu, 25 Jun 2026 14:38:45 +0200 Subject: [PATCH 086/101] Move taskList margin from inline JS style to styles.css --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 2 +- styles.css | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 9c113bf1..130a35d5 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.style.margin="0.3em 0 0 1.2em",taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.classList.add("mumie_multi_tasks_list"),taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 8a2443bb..d2afad3a 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.style.margin = '0.3em 0 0 1.2em';\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","margin","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.classList.add('mumie_multi_tasks_list');\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","classList","add","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 fcd4c25f..8483cbff 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -432,7 +432,7 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv taskCountLabel.textContent = label; }); }); - taskList.style.margin = '0.3em 0 0 1.2em'; + taskList.classList.add('mumie_multi_tasks_list'); taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem)); summary.appendChild(taskCountLabel); summary.appendChild(taskList); diff --git a/styles.css b/styles.css index 49d4d744..bacdc1f6 100644 --- a/styles.css +++ b/styles.css @@ -25,6 +25,10 @@ border-bottom: 1px solid black; } +.mumie_multi_tasks_list { + margin: 0.3em 0 0 1.2em; +} + #mumie_multi_tasks_summary { margin: 0.5em 0; padding: 0.5em; From 102501fe2aeb2d66c7056924461aa12f5e81dd09 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Thu, 25 Jun 2026 14:42:15 +0200 Subject: [PATCH 087/101] Rename taskCountLabel/label to summaryHeading/headingText --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index 130a35d5..fd808bc2 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const taskCountLabel=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(label){taskCountLabel.textContent=label}))})),taskList.classList.add("mumie_multi_tasks_list"),taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(taskCountLabel),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const summaryHeading=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(headingText){summaryHeading.textContent=headingText}))})),taskList.classList.add("mumie_multi_tasks_list"),taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(summaryHeading),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 d2afad3a..cc28f5d2 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const taskCountLabel = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(label) {\n taskCountLabel.textContent = label;\n });\n });\n taskList.classList.add('mumie_multi_tasks_list');\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(taskCountLabel);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","taskCountLabel","taskList","Str","get_string","length","then","label","classList","add","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const summaryHeading = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(headingText) {\n summaryHeading.textContent = headingText;\n });\n });\n taskList.classList.add('mumie_multi_tasks_list');\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(summaryHeading);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","summaryHeading","taskList","Str","get_string","length","then","headingText","classList","add","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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 8483cbff..194d99fc 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -424,17 +424,17 @@ define(['jquery', 'core/templates', 'core/modal_factory', 'auth_mumie/mumie_serv return taskListItem; }); summary.innerHTML = ''; - const taskCountLabel = document.createElement('div'); + const summaryHeading = document.createElement('div'); const taskList = document.createElement('ul'); require(['core/str'], function(Str) { Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length) - .then(function(label) { - taskCountLabel.textContent = label; + .then(function(headingText) { + summaryHeading.textContent = headingText; }); }); taskList.classList.add('mumie_multi_tasks_list'); taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem)); - summary.appendChild(taskCountLabel); + summary.appendChild(summaryHeading); summary.appendChild(taskList); summary.style.display = 'block'; } From 2f16cdf460b02eb4e416a835faf8aa4586149e09 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Thu, 25 Jun 2026 15:47:21 +0200 Subject: [PATCH 088/101] Update Changelog. --- changelog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/changelog.md b/changelog.md index 1a0be6f4..8d36cfa6 100644 --- a/changelog.md +++ b/changelog.md @@ -7,10 +7,16 @@ All important changes to this plugin will be documented in this file. - Teachers can now apply the deadline setting to multiple MUMIE Tasks at once using the multi-edit feature - Tasks without a 'Deadline' working period show a warning when deadline transfer is selected - Validation prevents transferring a deadline to tasks that were not created with working period type 'Deadline' +- Teachers can now create multiple MUMIE Tasks at once using the Multi Problem Selector ### Fixed - MUMIE Task no longer shows working period descriptions for all options simultaneously - Inconsistent working period description texts corrected +- Switching to multi-select mode now correctly clears the name, course, and problem fields +- The multi-select button is now disabled when editing an existing MUMIE Task + +### Changed +- Error messages when adding a MUMIE server are now displayed in a modal dialog ## [v1.9.1] - 2025-07-03 ### Changed From 62f3bcd913bfee2976e0cde559132fc39dfabd28 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Thu, 25 Jun 2026 15:50:56 +0200 Subject: [PATCH 089/101] Add use statements for mod_mumie classes in externallib.php --- externallib.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/externallib.php b/externallib.php index ee292272..da8276ba 100644 --- a/externallib.php +++ b/externallib.php @@ -26,6 +26,8 @@ defined('MOODLE_INTERNAL') || die; use mod_mumie\locallib; +use mod_mumie\form_field_decoder; +use mod_mumie\mumie_task_validator; require_once($CFG->libdir . "/externallib.php"); @@ -193,7 +195,7 @@ public static function create_multiple_mumie_tasks($contextid, $section, $tasksf $formfields = []; parse_str($taskpost, $formfields); - $instancedata = \mod_mumie\form_field_decoder::from_form_fields($formfields); + $instancedata = form_field_decoder::from_form_fields($formfields); locallib::clean_up_duration_values($instancedata); $instancedata->modulename = 'mumie'; @@ -207,7 +209,7 @@ public static function create_multiple_mumie_tasks($contextid, $section, $tasksf $instancedata->grade = (int)$instancedata->points; } - $errors = \mod_mumie\mumie_task_validator::get_errors((array)$instancedata, new stdClass()); + $errors = mumie_task_validator::get_errors((array)$instancedata, new stdClass()); if (!empty($errors)) { throw new moodle_exception('mumie_multi_task_validation_error', 'mod_mumie', '', reset($errors)); } From 8d518d0b0b71f61b71a26c4430e680511bfd9fd3 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Thu, 25 Jun 2026 15:53:33 +0200 Subject: [PATCH 090/101] =?UTF-8?q?=E2=97=8F=20Remove=20redundant=20requir?= =?UTF-8?q?e=5Fonce=20for=20lib.php=20in=20externallib.php?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- externallib.php | 1 - 1 file changed, 1 deletion(-) diff --git a/externallib.php b/externallib.php index da8276ba..9648b122 100644 --- a/externallib.php +++ b/externallib.php @@ -162,7 +162,6 @@ public static function create_multiple_mumie_tasks($contextid, $section, $tasksf global $CFG, $DB; require_once($CFG->dirroot . '/course/modlib.php'); - require_once($CFG->dirroot . '/mod/mumie/lib.php'); require_once($CFG->dirroot . '/mod/mumie/locallib.php'); require_once($CFG->dirroot . '/mod/mumie/forms/form_field_decoder.php'); require_once($CFG->dirroot . '/mod/mumie/forms/mumie_task_validator.php'); From 4cc84f43102f04b7d3ea8d6400c0e9666bea4873 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 26 Jun 2026 10:18:18 +0200 Subject: [PATCH 091/101] Updated changelog.md --- changelog.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 8d36cfa6..101e291a 100644 --- a/changelog.md +++ b/changelog.md @@ -7,16 +7,18 @@ All important changes to this plugin will be documented in this file. - Teachers can now apply the deadline setting to multiple MUMIE Tasks at once using the multi-edit feature - Tasks without a 'Deadline' working period show a warning when deadline transfer is selected - Validation prevents transferring a deadline to tasks that were not created with working period type 'Deadline' -- Teachers can now create multiple MUMIE Tasks at once using the Multi Problem Selector +- SSO when opening the Multi Problem Selector ### Fixed - MUMIE Task no longer shows working period descriptions for all options simultaneously - Inconsistent working period description texts corrected -- Switching to multi-select mode now correctly clears the name, course, and problem fields -- The multi-select button is now disabled when editing an existing MUMIE Task ### Changed - Error messages when adding a MUMIE server are now displayed in a modal dialog +- Multi Problem Selector now creates MUMIE Tasks via form submission instead of drag-and-drop +- Drag-and-drop creation of MUMIE Tasks is no longer supported +- Settings configured on the form (points, deadline, container, etc.) are now applied to all tasks created via the Multi Problem Selector +- Multi Problem Selector button is unavailable when editing an existing MUMIE Task ## [v1.9.1] - 2025-07-03 ### Changed From e5ca4082946f2f0992578c5d7f7208b24e5c54fc Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 26 Jun 2026 10:23:45 +0200 Subject: [PATCH 092/101] Remove Error Message line from Changed Section in readme. --- changelog.md | 1 - 1 file changed, 1 deletion(-) diff --git a/changelog.md b/changelog.md index 101e291a..90092983 100644 --- a/changelog.md +++ b/changelog.md @@ -14,7 +14,6 @@ All important changes to this plugin will be documented in this file. - Inconsistent working period description texts corrected ### Changed -- Error messages when adding a MUMIE server are now displayed in a modal dialog - Multi Problem Selector now creates MUMIE Tasks via form submission instead of drag-and-drop - Drag-and-drop creation of MUMIE Tasks is no longer supported - Settings configured on the form (points, deadline, container, etc.) are now applied to all tasks created via the Multi Problem Selector From e04bd00915f1bfd694f17f04d8b12a37c1c3fa99 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 26 Jun 2026 11:34:15 +0200 Subject: [PATCH 093/101] Reset Version. --- version.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.php b/version.php index 88262dae..d7e9063f 100644 --- a/version.php +++ b/version.php @@ -25,10 +25,10 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2026060900; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2025070300; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2022112800; // 4.1 LTS -$plugin->release = "v1.9.2"; +$plugin->release = "v1.9.1"; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = [ 'auth_mumie' => 2025051500, From 7fe56fccd7ad764a1f8f9cae8686d9fbb8dee826 Mon Sep 17 00:00:00 2001 From: Alexander Werner Date: Fri, 26 Jun 2026 11:47:33 +0200 Subject: [PATCH 094/101] update SSO info in changelog.md. --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 90092983..9f37c5f9 100644 --- a/changelog.md +++ b/changelog.md @@ -7,7 +7,7 @@ All important changes to this plugin will be documented in this file. - Teachers can now apply the deadline setting to multiple MUMIE Tasks at once using the multi-edit feature - Tasks without a 'Deadline' working period show a warning when deadline transfer is selected - Validation prevents transferring a deadline to tasks that were not created with working period type 'Deadline' -- SSO when opening the Multi Problem Selector +- SSO when opening the Multi Problem Selector for the Problem Pool ### Fixed - MUMIE Task no longer shows working period descriptions for all options simultaneously From e253b46fae424e866e9cc7ff86ba8f3e90069cfb Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Sat, 27 Jun 2026 13:07:31 +0200 Subject: [PATCH 095/101] update min.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 fd808bc2..e7d39ab2 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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const summaryHeading=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(headingText){summaryHeading.textContent=headingText}))})),taskList.classList.add("mumie_multi_tasks_list"),taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(summaryHeading),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +define("mod_mumie/mod_form",["jquery","core/templates","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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const summaryHeading=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(headingText){summaryHeading.textContent=headingText}))})),taskList.classList.add("mumie_multi_tasks_list"),taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(summaryHeading),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 cc28f5d2..8200b22e 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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const summaryHeading = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(headingText) {\n summaryHeading.textContent = headingText;\n });\n });\n taskList.classList.add('mumie_multi_tasks_list');\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(summaryHeading);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","summaryHeading","taskList","Str","get_string","length","then","headingText","classList","add","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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', '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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const summaryHeading = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(headingText) {\n summaryHeading.textContent = headingText;\n });\n });\n taskList.classList.add('mumie_multi_tasks_list');\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(summaryHeading);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","summaryHeading","taskList","Str","get_string","length","then","headingText","classList","add","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"mappings":"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"} \ No newline at end of file From 6cd1add1e8321dbff54f3cfede1d21cec3eaa1e4 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Sat, 27 Jun 2026 13:30:39 +0200 Subject: [PATCH 096/101] fix changelog --- changelog.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index 1242d858..2eead1fc 100644 --- a/changelog.md +++ b/changelog.md @@ -12,18 +12,16 @@ All important changes to this plugin will be documented in this file. ### Changed - Plugin now requires Moodle 4.3 - Support Moodle 5.2 +- Multi Problem Selector now creates MUMIE Tasks via form submission instead of drag-and-drop +- Drag-and-drop creation of MUMIE Tasks is no longer supported +- Settings configured on the form (points, deadline, container, etc.) are now applied to all tasks created via the Multi Problem Selector +- Multi Problem Selector button is unavailable when editing an existing MUMIE Task ### Fixed - MUMIE Task no longer shows working period descriptions for all options simultaneously - Inconsistent working period description texts corrected - Deleting a due date extension no longer fails with a server error -### Changed -- Multi Problem Selector now creates MUMIE Tasks via form submission instead of drag-and-drop -- Drag-and-drop creation of MUMIE Tasks is no longer supported -- Settings configured on the form (points, deadline, container, etc.) are now applied to all tasks created via the Multi Problem Selector -- Multi Problem Selector button is unavailable when editing an existing MUMIE Task - ## [v1.9.1] - 2025-07-03 ### Changed - Refactored code to comply with PHP 8.4 From 99b8a7783267ae16682d9ff79c4a675751922ece Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Sat, 27 Jun 2026 14:51:04 +0200 Subject: [PATCH 097/101] remove dead "require passing grade" completion option --- backup/moodle2/backup_mumie_stepslib.php | 2 +- changelog.md | 5 +- db/install.xml | 1 - db/upgrade.php | 21 +++++++++ forms/mumie_task_validator.php | 27 ----------- lang/de/mumie.php | 8 ---- lang/en/mumie.php | 6 --- lib.php | 33 -------------- mod_form.php | 58 ------------------------ tests/generator/lib.php | 1 - version.php | 3 +- 11 files changed, 28 insertions(+), 137 deletions(-) diff --git a/backup/moodle2/backup_mumie_stepslib.php b/backup/moodle2/backup_mumie_stepslib.php index 5bc9ccc7..60b73ff4 100644 --- a/backup/moodle2/backup_mumie_stepslib.php +++ b/backup/moodle2/backup_mumie_stepslib.php @@ -31,7 +31,7 @@ protected function define_structure() { 'name', 'intro', 'introformat', 'timecreated', 'timemodified', 'taskurl', 'launchcontainer', 'mumie_course', 'language', 'server', 'mumie_coursefile', - 'lastsync', 'points', 'completionpass', 'privategradepool', 'duedate', 'isgraded']); + 'lastsync', 'points', 'privategradepool', 'duedate', 'isgraded']); $serverconfig = new backup_nested_element("serverconfig", ['id'], ['name', 'url_prefix']); $mumie->add_child($serverconfig); diff --git a/changelog.md b/changelog.md index 2eead1fc..736a6a2b 100644 --- a/changelog.md +++ b/changelog.md @@ -13,10 +13,13 @@ All important changes to this plugin will be documented in this file. - Plugin now requires Moodle 4.3 - Support Moodle 5.2 - Multi Problem Selector now creates MUMIE Tasks via form submission instead of drag-and-drop -- Drag-and-drop creation of MUMIE Tasks is no longer supported - Settings configured on the form (points, deadline, container, etc.) are now applied to all tasks created via the Multi Problem Selector - Multi Problem Selector button is unavailable when editing an existing MUMIE Task +### Removed +- Drag-and-drop creation of MUMIE Tasks is no longer supported +- The "Require passing grade" completion option in activity settings; use Moodle's built-in "Receive a grade" → "Passing grade" option instead. + ### Fixed - MUMIE Task no longer shows working period descriptions for all options simultaneously - Inconsistent working period description texts corrected diff --git a/db/install.xml b/db/install.xml index e0b9d56d..587d8bdb 100644 --- a/db/install.xml +++ b/db/install.xml @@ -21,7 +21,6 @@ - diff --git a/db/upgrade.php b/db/upgrade.php index cf8cbd60..4b69ff09 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -91,6 +91,10 @@ function xmldb_mumie_upgrade($oldversion) { addfieldifmissing('mumie', 'timelimit', XMLDB_TYPE_INTEGER, '10', null, false, null, null, null); upgrade_plugin_savepoint(true, 2025031200, 'mod', 'mumie'); } + if ($oldversion < 2026062300) { + dropfieldifexists('mumie', 'completionpass'); + upgrade_plugin_savepoint(true, 2026062300, 'mod', 'mumie'); + } return true; } @@ -143,3 +147,20 @@ function addfieldifmissing( $dbman->add_field($table, $field); } } + +/** + * Drops a field from a table if it exists. + * + * @param string $tablename + * @param string $fieldname + * @return void + */ +function dropfieldifexists(string $tablename, string $fieldname): void { + global $DB; + $dbman = $DB->get_manager(); + $table = new xmldb_table($tablename); + $field = new xmldb_field($fieldname); + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } +} diff --git a/forms/mumie_task_validator.php b/forms/mumie_task_validator.php index 25795a11..ed3dfcab 100644 --- a/forms/mumie_task_validator.php +++ b/forms/mumie_task_validator.php @@ -46,7 +46,6 @@ class mumie_task_validator { public static function get_errors(array $data, \stdClass $current): array { $errors = []; $errors = array_merge($errors, self::check_required($data)); - $errors = array_merge($errors, self::check_completion($data, $current)); $errors = array_merge($errors, self::check_isgraded($data)); $errors = array_merge($errors, self::check_duration($data)); $errors = array_merge($errors, self::check_worksheet($data)); @@ -81,32 +80,6 @@ private static function check_required(array $data): array { return $errors; } - /** - * Validates the completion settings of a MUMIE activity. - * - * Ensures that if automatic completion tracking is enabled and completion requires passing, - * then a valid passing grade must be set. Adds appropriate errors if this condition is not met. - * - * @param array $data Form data submitted by the user. - * @param \stdClass $current The current MUMIE activity instance for fallback values. - * @return array Associative array of validation errors. - */ - private static function check_completion(array $data, \stdClass $current): array { - $errors = []; - if (($data['completion'] ?? null) == COMPLETION_TRACKING_AUTOMATIC) { - $completionpass = $data['completionpass'] ?? $current->completionpass; - $gradepass = grade_floatval($data['gradepass'] ?? 0); - - if ($completionpass && $gradepass == 0) { - $completionpassisset = isset($data['completionpass']); - $key = $completionpassisset ? 'completionpassgroup' : 'gradepass'; - $stringkey = $completionpassisset ? 'gradetopassnotset' : 'gradetopassmustbeset'; - $errors[$key] = get_string($stringkey, 'mumie'); - } - } - return $errors; - } - /** * Validates that the grading status of an existing MUMIE task has not been changed. * diff --git a/lang/de/mumie.php b/lang/de/mumie.php index 8b154272..b202e8b9 100644 --- a/lang/de/mumie.php +++ b/lang/de/mumie.php @@ -24,14 +24,6 @@ */ defined('MOODLE_INTERNAL') || die; -$string['completionpass'] = 'Bewertung für Bestehen notwendig'; -$string['completionpass_help'] = 'Wenn diese Option aktiviert ist, wird die Aktivität als abgeschlossen betrachtet, sobald eine Bewertung vorliegt. Icons für die erfolgreiche oder erfolglose Bearbeitung können angezeigt werden, -wenn dafür eine Bewertungsgrenze festgelegt wurde. -

Bitte beachten Sie:
-Noten für MUMIE Tasks werden nur aktualisiert, wenn sie im Moodle-Gradebook angezeigt werden. Wenn Sie aktuelle Informationen über den Aktivitätsabschluss aller Studierenden sehen möchten, -sollten zu daher zuvor die Bewerterübersicht öffnen.'; -$string['gradetopassmustbeset'] = 'Die Bestehensgrenze kann nicht 0 sein, da der Aktivitätsabschluss vom Erreichen dieser Grenze abhängig ist. Bitte geben Sie daher einen Wert über 0 ein.'; -$string['gradetopassnotset'] = 'Dieser Test hat keine Bestehensgrenze.'; $string['modulename'] = 'MUMIE Task'; $string['modulename_help'] = '

Dieses Aktivität-Modul ermöglicht die Nutzung von Inhalten der MUMIE-Plattform auf Moodle und eine automatische Synchronisierung der dort erzielten Noten. Ein MUMIE Task steht hierbei für eine einzelne benotete Aufgabe eines MUMIE-Kurses.

diff --git a/lang/en/mumie.php b/lang/en/mumie.php index 4edd0442..bc9bacc8 100644 --- a/lang/en/mumie.php +++ b/lang/en/mumie.php @@ -24,12 +24,6 @@ */ defined('MOODLE_INTERNAL') || die; -$string['completionpass'] = 'Require passing grade'; -$string['completionpass_help'] = 'If enabled, this activity is considered completed when the student receives a passing grade, with the pass grade set in the gradebook. -

Please Note:
-Grades for MUMIE Tasks are only updated, when the gradebook is opened. If you want the current completion status of all students, remember to open the gradebook overview page first'; -$string['gradetopassmustbeset'] = 'Grade to pass cannot be zero as this activity has its completion method set to require passing grade. Please set a non-zero value.'; -$string['gradetopassnotset'] = 'This MUMIE task does not have a grade to pass set so you cannot use this option. Please use the require grade setting instead.'; $string['modulename'] = 'MUMIE Task'; $string['modulename_help'] = '

This activity module enables the usage of content from the MUMIE e-learning platform and automatic grade synchronization. A MUMIE tasks represents an individual graded problem from a MUMIE course.

What is MUMIE?

diff --git a/lib.php b/lib.php index fd643b25..1b083c65 100644 --- a/lib.php +++ b/lib.php @@ -202,8 +202,6 @@ function mumie_supports($feature) { switch ($feature) { case FEATURE_GRADE_HAS_GRADE: return true; - case FEATURE_COMPLETION_HAS_RULES: - return true; case FEATURE_BACKUP_MOODLE2: return true; case FEATURE_SHOW_DESCRIPTION: @@ -283,37 +281,6 @@ function mumie_before_standard_top_of_body_html() { return locallib::callbackimpl_before_standard_top_of_body_html(); } -/** - * Obtains the automatic completion state for this MUMIE task - * - * This is a code fragment copied from mod_quiz version 2018051400 - * @param object $course Course - * @param object $cm Course-module - * @param int $userid User ID - * @param bool $type Type of comparison (or/and; can be used as return value if no conditions) - * @return bool True if completed, false if not. (If no conditions, then return - * value depends on comparison type) - */ -function mumie_get_completion_state($course, $cm, $userid, $type) { - global $DB, $CFG; - $mumie = $DB->get_record('mumie', ['id' => $cm->instance], '*', MUST_EXIST); - - if ($mumie->completionpass) { - require_once($CFG->libdir . '/gradelib.php'); - $item = grade_item::fetch(['courseid' => $course->id, 'itemtype' => 'mod', - 'itemmodule' => 'mumie', 'iteminstance' => $cm->instance, 'outcomeid' => null]); - - if ($item) { - $grades = grade_grade::fetch_users_grades($item, [$userid], false); - if (!empty($grades[$userid])) { - return $grades[$userid]->is_passed($item); - } - } - } - return false; -} - - /** * Get mumieserver_form as a fragment * diff --git a/mod_form.php b/mod_form.php index ad0c57ee..79175dc0 100644 --- a/mod_form.php +++ b/mod_form.php @@ -286,52 +286,6 @@ private function get_server_options(): array { return $serveroptions; } - /** - * Provide option to mark an activity automatically as completed once a passing grade was archived - * - * This function is copied from mod_quiz version 2018051400 - * @return array containing the name of the mform group that has been added to the form - */ - public function add_completion_rules(): array { - $mform = $this->_form; - $items = []; - - $group = []; - $completionpasselement = $this->get_completion_rule_element_name('completionpass'); - $group[] = $mform->createElement( - 'advcheckbox', - $completionpasselement, - null, - get_string('completionpass', 'mumie'), - ['group' => 'cpass'] - ); - $completionusegradeelement = $this->get_completion_rule_element_name('completionusegrade'); - $mform->disabledIf($completionpasselement, $completionusegradeelement, 'notchecked'); - $completionpassgroupelement = $this->get_completion_rule_element_name('completionpassgroup'); - $mform->addGroup($group, $completionpassgroupelement, get_string('completionpass', 'mumie'), '   ', false); - $mform->addHelpButton($completionpassgroupelement, 'completionpass', 'mumie'); - $items[] = $completionpassgroupelement; - return $items; - } - - /** - * Get the completion rule's element name. - * - * Conditionally add suffix for Moodle >= 4.3. - * - * @param string $rawname The raw name of the completion rule. - * @return string The properly suffixed element name. - */ - private function get_completion_rule_element_name($rawname): string { - global $CFG; - if ($CFG->branch < 403) { - $suffix = ''; - } else { - $suffix = $this->get_suffix(); - } - return $rawname . $suffix; - } - /** * Disable all options for grades if the user has chosen to link a course instead of a problem. */ @@ -618,18 +572,6 @@ private function set_general_data($data): void { } } - /** - * Called during validation. Indicates whether a module-specific completion rule is selected. - * - * @param array $data Input data (not yet validated) - * @return bool True if one or more rules is enabled, false if none are. - */ - public function completion_rule_enabled($data): bool { - $completionpasselement = $this->get_completion_rule_element_name('completionpass'); - return !empty($data[$completionpasselement]); - } - - /** * The decision regarding gradepools is final. We need to know whether we should disable the selection boxes. * diff --git a/tests/generator/lib.php b/tests/generator/lib.php index 2e045503..b469529a 100644 --- a/tests/generator/lib.php +++ b/tests/generator/lib.php @@ -43,7 +43,6 @@ public function create_instance($record = null, ?array $options = null) { 'mumie_course' => '', 'lastsync' => 0, 'points' => 100, - 'completionpass' => 0, 'use_hashed_id' => 1, 'duedate' => 0, 'privategradepool' => 1, diff --git a/version.php b/version.php index 1bc508ff..cf029694 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,8 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2025070300; // The current module version (Date: YYYYMMDDXX). +// todo: before release, the version in /db/upgrade.php should match the updated plugin version +$plugin->version = 2026062300; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2023100900; // 4.3 $plugin->release = "v1.9.1"; From e8d1da5be424389e5b81ed6a5a62a9d6187f9715 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Sat, 27 Jun 2026 15:50:53 +0200 Subject: [PATCH 098/101] fix multi-problem-selection section placement on moodle 5.1+ --- amd/build/mod_form.min.js | 2 +- amd/build/mod_form.min.js.map | 2 +- amd/src/mod_form.js | 5 +++-- mod_form.php | 12 ++++++++++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/amd/build/mod_form.min.js b/amd/build/mod_form.min.js index e7d39ab2..1884b2b6 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","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,contextId;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const summaryHeading=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(headingText){summaryHeading.textContent=headingText}))})),taskList.classList.add("mumie_multi_tasks_list"),taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(summaryHeading),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,section=parseInt(new URLSearchParams(window.location.search).get("section")||0),submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); +define("mod_mumie/mod_form",["jquery","core/templates","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,contextId,section;const durationController=function(){const durationSelector=document.getElementById("id_duration_selector"),gradedElem=document.getElementById("id_mumie_isgraded");function isUngraded(){return"0"===gradedElem.value}function updateDurationElements(){var _document$querySelect;isUngraded()?(durationSelector.setAttribute("disabled","disabled"),durationSelector.value="unlimited"):durationSelector.removeAttribute("disabled");"unlimited"===durationSelector.value?(document.getElementById("fitem_id_unlimited_info").style.display="",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none"):"duedate"===durationSelector.value?(document.getElementById("fitem_id_duedate").style.display="",document.getElementById("fitem_id_duedate_info").style.display="",document.getElementById("fitem_id_unlimited_info").style.display="none",document.getElementById("fitem_id_timelimit").style.display="none",document.getElementById("fitem_id_timelimit_info").style.display="none"):"timelimit"===durationSelector.value&&(document.getElementById("fitem_id_timelimit").style.display="",document.getElementById("fitem_id_timelimit_info").style.display="",document.getElementById("fitem_id_duedate").style.display="none",document.getElementById("fitem_id_duedate_info").style.display="none",document.getElementById("fitem_id_unlimited_info").style.display="none");const duedatePropRow=null===(_document$querySelect=document.querySelector('[name="mumie_multi_edit_property"][value="duedate"]'))||void 0===_document$querySelect?void 0:_document$querySelect.closest("tr");if(duedatePropRow){const show="duedate"===durationSelector.value;if(duedatePropRow.style.display=show?"":"none",!show){const duedatePropertyCheckbox=duedatePropRow.querySelector('[name="mumie_multi_edit_property"]');duedatePropertyCheckbox&&duedatePropertyCheckbox.checked&&(duedatePropertyCheckbox.checked=!1,duedatePropertyCheckbox.dispatchEvent(new Event("change")))}}}return{init:function(){durationSelector.onchange=function(){updateDurationElements()},window.addEventListener("load",(()=>{updateDurationElements()})),updateDurationElements()},setDurationElements:updateDurationElements,isUngraded:isUngraded,setGradedElemValue:function(isGraded){gradedElem.value=isGraded?"1":"0"},getGradedElemValue:function(){return gradedElem.value}}}(),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)}}}(),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)try{const importObj=JSON.parse(event.data);Array.isArray(importObj)?taskController.setMultiSelection(importObj):(applyPickerPayloadToForm(importObj),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)}))),sendSuccess(),window.focus()}catch(error){!function(){sendResponse({success:!1,message:arguments.length>0&&void 0!==arguments[0]?arguments[0]:""})}(error.message)}}),!1)}function buildURL(){let multiSelect=arguments.length>0&&void 0!==arguments[0]&&arguments[0];const gradingType=multiSelect?"all":taskController.getGradingType(),selectedServer=serverController.getSelectedServer().urlprefix,useSSO=shouldUseSSO(lmsSelectorUrl,selectedServer),base=useSSO?"/auth/mumie/problem_selector.php?org="+mumieOrg+"&serverurl="+encodeURIComponent(selectedServer)+"&problemlang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&gradingtype="+gradingType+"&contextid="+contextId:lmsSelectorUrl+"/lms-problem-selector?org="+mumieOrg+"&serverUrl="+encodeURIComponent(selectedServer)+"&problemLang="+langController.getSelectedLanguage()+"&origin="+encodeURIComponent(window.location.origin)+"&uiLang="+systemLanguage+"&gradingType="+gradingType+"&multiCourse=true&worksheet=true";if(multiSelect)return base+(useSSO?"&multiselect=true":"&multiSelect=true");const selection=taskController.getDelocalizedTaskLink();return selection?base+"&selection="+selection:base}function shouldUseSSO(problemSelectorUrl,selectedServerUrl){return new URL(problemSelectorUrl).origin===new URL(selectedServerUrl).origin}return{init:function(){problemSelectorButton.onclick=function(){problemSelectorWindow=window.open(buildURL(),"_blank")},window.onclose=function(){sendSuccess()},window.addEventListener("beforeunload",(function(){sendSuccess()}),!1),addMessageListener(),multiProblemSelectorButton.onclick=function(e){e.preventDefault(),problemSelectorWindow=window.open(buildURL(!0),"_blank","toolbar=0,location=0,menubar=0")}},disable:function(){problemSelectorButton.disabled=!0}}}();function applyPickerPayloadToForm(payload){var _payload$worksheet;const isGraded=!1!==payload.isGraded,worksheet=null!==(_payload$worksheet=payload.worksheet)&&void 0!==_payload$worksheet?_payload$worksheet:null;courseController.setCourse(payload.path_to_coursefile),langController.setLanguage(payload.language),taskController.setSelection(payload.link,payload.language,payload.name),taskController.setIsGraded(isGraded),worksheetController.setWorksheet(worksheet)}const 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))},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){languageElem.value=lang}}}(),taskController=function(){const taskSelectionInput=document.getElementsByName("taskurl")[0],nameElem=document.getElementById("id_name"),taskDisplayElement=document.getElementById("id_task_display_element");function updateTaskDisplayElement(localizedLink){taskDisplayElement.value=localizedLink}function updateTaskUri(link,language){const localizedLink=function(link,language){return link+"?lang="+language}(link,language);taskSelectionInput.value=localizedLink,updateTaskDisplayElement(localizedLink)}function setMultiSelection(tasks){const tasksField=document.getElementsByName("mumie_multi_tasks")[0],summary=document.getElementById("mumie_multi_tasks_summary");if(tasksField&&(tasksField.value=JSON.stringify(tasks)),summary){const taskListItems=tasks.map((task=>{const taskListItem=document.createElement("li");return taskListItem.textContent=task.name,taskListItem}));summary.innerHTML="";const summaryHeading=document.createElement("div"),taskList=document.createElement("ul");require(["core/str"],(function(Str){Str.get_string("mumie_multi_tasks_selected","mod_mumie",tasks.length).then((function(headingText){summaryHeading.textContent=headingText}))})),taskList.classList.add("mumie_multi_tasks_list"),taskListItems.forEach((taskListItem=>taskList.appendChild(taskListItem))),summary.appendChild(summaryHeading),summary.appendChild(taskList),summary.style.display="block"}const nameField=document.getElementById("id_name");nameField.disabled=!0,nameField.value="",nameField.removeAttribute("required");const taskDisplayElem=document.getElementById("id_task_display_element");taskDisplayElem&&(taskDisplayElem.value="");const courseNameElem=document.getElementById("id_mumie_course");courseNameElem&&(courseNameElem.value="");const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display="none"}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display="none")}return{init:function(){updateTaskDisplayElement(taskSelectionInput.value)},setSelection:function(link,language,name){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];tasksField&&(tasksField.value="");const summary=document.getElementById("mumie_multi_tasks_summary");summary&&(summary.style.display="none",summary.innerHTML="");const nameField=document.getElementById("id_name");nameField&&(nameField.disabled=!1,nameField.setAttribute("required","required"));const nameFieldContainer=document.getElementById("fitem_id_name");nameFieldContainer&&nameFieldContainer.querySelectorAll('.req, .text-danger, [title="Required field"]').forEach((requiredIndicator=>{requiredIndicator.style.display=""}));const requiredLegend=document.querySelector(".fdescription.required");requiredLegend&&(requiredLegend.style.display=""),updateTaskUri(link,language),function(name){nameElem.value=name}(name)},setIsGraded:function(isGraded){durationController.setGradedElemValue(isGraded),function(){const disabled=durationController.isUngraded();document.getElementById("id_points").disabled=disabled,document.getElementById("id_gradepass").disabled=disabled,document.getElementById("id_gradecat").disabled=disabled,durationController.setDurationElements()}()},getGradingType:function(){const isGraded=durationController.getGradedElemValue();return"1"===isGraded?"graded":"0"===isGraded?"ungraded":"all"},getDelocalizedTaskLink:function(){return(link=taskSelectionInput.value).includes("?lang=")?link.split("?lang=")[0]:link;var link},setMultiSelection:setMultiSelection,hasMultiTasks:function(){const tasksField=document.getElementsByName("mumie_multi_tasks")[0];return tasksField&&!!tasksField.value},submitMultiTasks:function(){var _document$getElements;const tasksField=document.getElementsByName("mumie_multi_tasks")[0],courseId=null===(_document$getElements=document.getElementsByName("course")[0])||void 0===_document$getElements?void 0:_document$getElements.value,submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form"),tasks=JSON.parse(tasksField.value),tasksFormData=tasks.map((task=>(applyPickerPayloadToForm(task),function(form){const disabledFields=Array.from(form.querySelectorAll(":disabled"));disabledFields.forEach((field=>{field.disabled=!1}));try{const omit=["sesskey","_qf__mod_mumie_mod_form"];return Array.from(new FormData(form)).filter((_ref=>{let[key]=_ref;return!omit.includes(key)})).map((_ref2=>{let[key,value]=_ref2;return encodeURIComponent(key)+"="+encodeURIComponent(value)})).join("&")}finally{disabledFields.forEach((field=>{field.disabled=!0}))}}(form))));setMultiSelection(tasks),require(["core/ajax","core/notification"],(function(Ajax,notification){Ajax.call([{methodname:"mod_mumie_create_multiple_mumie_tasks",args:{contextid:parseInt(contextId),section:section,tasksformdata:tasksFormData}}])[0].done((function(){window.location.href=M.cfg.wwwroot+"/course/view.php?id="+courseId})).fail((function(error){notification.alert("",error.message)}))}))}}}(),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");function setPropertySelectionListeners(){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),function(){const duedateSelected=Array.from(propertySelectionInputs).some((checkbox=>"duedate"===checkbox.value&&checkbox.checked));document.querySelectorAll(".mumie-form-working-period-not-duedate-warning").forEach((function(elem){elem.style.display=duedateSelected?"":"none"}))}()}}))}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)}})),setPropertySelectionListeners(),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)}}))}}}(),worksheetController=function(){const worksheetElement=document.getElementById("id_mumie_worksheet");return{setWorksheet:function(worksheet){worksheet?worksheetElement.setAttribute("value",JSON.stringify(worksheet)):worksheetElement.removeAttribute("value")}}}();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(contextIdParam,prbSelectorUrl,lang,sectionParam){lmsSelectorUrl=prbSelectorUrl,systemLanguage=lang,contextId=contextIdParam,section=sectionParam;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(),multiTaskEditController.init(),problemSelectorController.init(),durationController.init()):disableDropDownMenus("mumie_form_no_server_conf"),addServerButton&&require(["auth_mumie/mumie_server_config"],(function(MumieServer){MumieServer.init(addServerButton,contextId)}));const submitButton=document.getElementById("id_submitbutton"),form=submitButton&&submitButton.closest("form");if(form){let cancelClicked=!1;const cancelButton=document.getElementById("id_cancel");cancelButton&&cancelButton.addEventListener("click",(function(){cancelClicked=!0})),form.addEventListener("submit",(function(e){cancelClicked?cancelClicked=!1:taskController.hasMultiTasks()&&(e.preventDefault(),taskController.submitMultiTasks())}))}}}})); //# 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 8200b22e..8f24a322 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', '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 let contextId;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const summaryHeading = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(headingText) {\n summaryHeading.textContent = headingText;\n });\n });\n taskList.classList.add('mumie_multi_tasks_list');\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(summaryHeading);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0);\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","summaryHeading","taskList","Str","get_string","length","then","headingText","classList","add","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","section","parseInt","URLSearchParams","search","get","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","isEdit","MumieServer","cancelClicked","cancelButton"],"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', '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 let contextId;\n let section;\n\n\n const durationController = (function() {\n\n const durationSelector = document.getElementById('id_duration_selector');\n const gradedElem = document.getElementById('id_mumie_isgraded');\n\n /**\n * Returns if task is ungraded like courses and articles.\n */\n function isUngraded() {\n return gradedElem.value === '0';\n }\n\n /**\n * Updates the visibility of elements around duration selector.\n */\n function updateDurationElements() {\n const disabled = isUngraded();\n if (disabled) {\n durationSelector.setAttribute('disabled', 'disabled');\n durationSelector.value = 'unlimited';\n } else {\n durationSelector.removeAttribute('disabled');\n }\n\n const displayNone = 'none';\n\n if (durationSelector.value === 'unlimited') {\n document.getElementById('fitem_id_unlimited_info').style.display = '';\n\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n } else if (durationSelector.value === 'duedate') {\n document.getElementById('fitem_id_duedate').style.display = '';\n document.getElementById('fitem_id_duedate_info').style.display = '';\n\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n document.getElementById('fitem_id_timelimit').style.display = displayNone;\n document.getElementById('fitem_id_timelimit_info').style.display = displayNone;\n } else if (durationSelector.value === 'timelimit') {\n document.getElementById('fitem_id_timelimit').style.display = '';\n document.getElementById('fitem_id_timelimit_info').style.display = '';\n\n document.getElementById('fitem_id_duedate').style.display = displayNone;\n document.getElementById('fitem_id_duedate_info').style.display = displayNone;\n document.getElementById('fitem_id_unlimited_info').style.display = displayNone;\n }\n\n const duedatePropRow = document\n .querySelector('[name=\"mumie_multi_edit_property\"][value=\"duedate\"]')\n ?.closest('tr');\n if (duedatePropRow) {\n const show = durationSelector.value === 'duedate';\n duedatePropRow.style.display = show ? '' : displayNone;\n if (!show) {\n const duedatePropertyCheckbox = duedatePropRow.querySelector('[name=\"mumie_multi_edit_property\"]');\n if (duedatePropertyCheckbox && duedatePropertyCheckbox.checked) {\n duedatePropertyCheckbox.checked = false;\n duedatePropertyCheckbox.dispatchEvent(new Event('change'));\n }\n }\n }\n }\n\n return {\n init: function() {\n durationSelector.onchange = function() {\n updateDurationElements();\n };\n window.addEventListener(\"load\", () => {\n updateDurationElements();\n });\n updateDurationElements();\n },\n setDurationElements: updateDurationElements,\n isUngraded: isUngraded,\n setGradedElemValue: function(isGraded) {\n gradedElem.value = isGraded ? '1' : '0';\n },\n getGradedElemValue: function() {\n return gradedElem.value;\n }\n };\n })();\n\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 };\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 a 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 a 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 try {\n const importObj = JSON.parse(event.data);\n if (Array.isArray(importObj)) {\n taskController.setMultiSelection(importObj);\n } else {\n applyPickerPayloadToForm(importObj);\n displayProblemSelectedMessage();\n }\n sendSuccess();\n window.focus();\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 /**\n * Builds the URL to the Problem Selector\n * @param {boolean} multiSelect Whether to build a multi-select URL\n * @returns {string} URL to the Problem Selector\n */\n function buildURL(multiSelect = false) {\n const gradingType = multiSelect ? 'all' : taskController.getGradingType();\n const selectedServer = serverController.getSelectedServer().urlprefix;\n const useSSO = shouldUseSSO(lmsSelectorUrl, selectedServer);\n\n const base = useSSO\n ? '/auth/mumie/problem_selector.php?' +\n 'org=' + mumieOrg +\n '&serverurl=' + encodeURIComponent(selectedServer) +\n '&problemlang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&gradingtype=' + gradingType +\n '&contextid=' + contextId\n : lmsSelectorUrl + '/lms-problem-selector?' +\n 'org=' + mumieOrg +\n '&serverUrl=' + encodeURIComponent(selectedServer) +\n '&problemLang=' + langController.getSelectedLanguage() +\n '&origin=' + encodeURIComponent(window.location.origin) +\n '&uiLang=' + systemLanguage +\n '&gradingType=' + gradingType +\n '&multiCourse=true' +\n '&worksheet=true';\n\n if (multiSelect) {\n return base + (useSSO ? '&multiselect=true' : '&multiSelect=true');\n }\n const selection = taskController.getDelocalizedTaskLink();\n return selection ? base + '&selection=' + selection : base;\n }\n\n /**\n * Determines whether the Single Sign-On (SSO) should be used when opening the Problem Selector.\n * SSO is only supposed to be used when the Problem Selector URL has the same origin as the\n * URL of the selected MUMIE server.\n *\n * @param {string} problemSelectorUrl - The URL of the problem selector.\n * @param {string} selectedServerUrl - The URL of the selected MUMIE server\n * @returns {boolean} Whether SSO should be used for the Problem Selector or not\n */\n function shouldUseSSO(problemSelectorUrl, selectedServerUrl) {\n return new URL(problemSelectorUrl).origin === new URL(selectedServerUrl).origin;\n }\n\n return {\n init: function() {\n problemSelectorButton.onclick = function() {\n problemSelectorWindow = window.open(buildURL(), '_blank');\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(buildURL(true), '_blank', 'toolbar=0,location=0,menubar=0');\n };\n },\n disable: function() {\n problemSelectorButton.disabled = true;\n },\n };\n })();\n\n /**\n * Apply a picker payload to the form's per-task fields.\n *\n * Single source of truth for picker-payload → form-field mapping.\n * Used by both the single-task postMessage handler and the multi-task\n * submit loop, so new picker fields only need to be wired here.\n *\n * @param {Object} payload picker payload for one task\n */\n function applyPickerPayloadToForm(payload) {\n const isGraded = payload.isGraded !== false;\n const worksheet = payload.worksheet ?? null;\n courseController.setCourse(payload.path_to_coursefile);\n langController.setLanguage(payload.language);\n taskController.setSelection(payload.link, payload.language, payload.name);\n taskController.setIsGraded(isGraded);\n worksheetController.setWorksheet(worksheet);\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 setCourse: function(courseFile) {\n updateCourseFilePath(courseFile);\n }\n };\n })();\n\n const langController = (function() {\n const languageElem = document.getElementById(\"id_language\");\n return {\n getSelectedLanguage: function() {\n return languageElem.value;\n },\n setLanguage: function(lang) {\n languageElem.value = lang;\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 LANG_REQUEST_PARAM_PREFIX = \"?lang=\";\n\n /**\n * Update the activity's name in the input field\n * @param {string} name\n */\n function updateName(name) {\n nameElem.value = name;\n }\n\n /**\n * @param {string} localizedLink\n */\n function updateTaskDisplayElement(localizedLink) {\n taskDisplayElement.value = localizedLink;\n }\n\n /**\n * Update task uri\n * @param {string} link\n * @param {string} language\n */\n function updateTaskUri(link, language) {\n const localizedLink = localizeLink(link, language);\n taskSelectionInput.value = localizedLink;\n updateTaskDisplayElement(localizedLink);\n }\n\n /**\n * Add lang request param to link\n * @param {string} link\n * @param {string} language\n * @returns {string} Link with lang request param\n */\n function localizeLink(link, language) {\n return link + LANG_REQUEST_PARAM_PREFIX + language;\n }\n\n /**\n * Remove lang request param from link\n * @param {string} link Link that may have lang request param\n * @returns {string} Link without lang request param\n */\n function delocalizeLink(link) {\n if (link.includes(LANG_REQUEST_PARAM_PREFIX)) {\n return link.split(LANG_REQUEST_PARAM_PREFIX)[0];\n }\n return link;\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 = durationController.isUngraded();\n document.getElementById('id_points').disabled = disabled;\n document.getElementById('id_gradepass').disabled = disabled;\n document.getElementById('id_gradecat').disabled = disabled;\n durationController.setDurationElements();\n }\n\n /**\n * Store selected tasks and update UI for multi-task creation.\n * @param {Array} tasks array of task objects from the selector\n */\n function setMultiSelection(tasks) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (tasksField) {\n tasksField.value = JSON.stringify(tasks);\n }\n if (summary) {\n const taskListItems = tasks.map(task => {\n const taskListItem = document.createElement('li');\n taskListItem.textContent = task.name;\n return taskListItem;\n });\n summary.innerHTML = '';\n const summaryHeading = document.createElement('div');\n const taskList = document.createElement('ul');\n require(['core/str'], function(Str) {\n Str.get_string('mumie_multi_tasks_selected', 'mod_mumie', tasks.length)\n .then(function(headingText) {\n summaryHeading.textContent = headingText;\n });\n });\n taskList.classList.add('mumie_multi_tasks_list');\n taskListItems.forEach(taskListItem => taskList.appendChild(taskListItem));\n summary.appendChild(summaryHeading);\n summary.appendChild(taskList);\n summary.style.display = 'block';\n }\n const nameField = document.getElementById('id_name');\n nameField.disabled = true;\n nameField.value = '';\n nameField.removeAttribute('required');\n const taskDisplayElem = document.getElementById('id_task_display_element');\n if (taskDisplayElem) { taskDisplayElem.value = ''; }\n const courseNameElem = document.getElementById('id_mumie_course');\n if (courseNameElem) { courseNameElem.value = ''; }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = 'none'; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = 'none';\n }\n }\n\n /**\n * Serialize a form into a URL-encoded POST string, omitting form mechanics\n * the webservice does not need (sesskey, qf form marker).\n *\n * Disabled form controls are temporarily enabled so FormData includes them:\n * the picker writes values to display-only inputs (e.g. mumie_course) that\n * the server-side validator still expects to receive.\n *\n * @param {HTMLFormElement} form\n * @returns {string}\n */\n function serializeFormFields(form) {\n const disabledFields = Array.from(form.querySelectorAll(':disabled'));\n disabledFields.forEach(field => { field.disabled = false; });\n try {\n const omit = ['sesskey', '_qf__mod_mumie_mod_form'];\n return Array.from(new FormData(form))\n .filter(([key]) => !omit.includes(key))\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&');\n } finally {\n disabledFields.forEach(field => { field.disabled = true; });\n }\n }\n\n /**\n * Submit multi-tasks via AJAX, then redirect to course.\n *\n * Builds one full form payload per task by applying each picker payload\n * to the live form and serializing it. The server treats each entry as\n * an independent single-task submission, so picker-payload → form-field\n * mapping lives in applyPickerPayloadToForm and is shared with the\n * single-task path. Validation runs server-side via the shared form\n * pipeline; errors surface as a modal alert with the validator's\n * localized message.\n */\n function submitMultiTasks() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n const courseId = document.getElementsByName('course')[0]?.value;\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n const tasks = JSON.parse(tasksField.value);\n\n const tasksFormData = tasks.map(task => {\n applyPickerPayloadToForm(task);\n return serializeFormFields(form);\n });\n\n // applyPickerPayloadToForm leaves the form in single-task mode of the last task;\n // restore the multi-task UI so the form is coherent if the AJAX call fails.\n setMultiSelection(tasks);\n\n require(['core/ajax', 'core/notification'], function(Ajax, notification) {\n Ajax.call([{\n methodname: 'mod_mumie_create_multiple_mumie_tasks',\n args: {\n contextid: parseInt(contextId),\n section: section,\n tasksformdata: tasksFormData,\n },\n }])[0].done(function() {\n window.location.href = M.cfg.wwwroot + '/course/view.php?id=' + courseId;\n }).fail(function(error) {\n notification.alert('', error.message);\n });\n });\n }\n\n return {\n init: function() {\n updateTaskDisplayElement(taskSelectionInput.value);\n },\n setSelection: function(link, language, name) {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n if (tasksField) {\n tasksField.value = '';\n }\n const summary = document.getElementById('mumie_multi_tasks_summary');\n if (summary) {\n summary.style.display = 'none';\n summary.innerHTML = '';\n }\n const nameField = document.getElementById('id_name');\n if (nameField) {\n nameField.disabled = false;\n nameField.setAttribute('required', 'required');\n }\n const nameFieldContainer = document.getElementById('fitem_id_name');\n if (nameFieldContainer) {\n nameFieldContainer.querySelectorAll('.req, .text-danger, [title=\"Required field\"]')\n .forEach(requiredIndicator => { requiredIndicator.style.display = ''; });\n }\n const requiredLegend = document.querySelector('.fdescription.required');\n if (requiredLegend) {\n requiredLegend.style.display = '';\n }\n updateTaskUri(link, language);\n updateName(name);\n },\n setIsGraded: function(isGraded) {\n durationController.setGradedElemValue(isGraded);\n updateGradeEditability();\n },\n getGradingType: function() {\n const isGraded = durationController.getGradedElemValue();\n if (isGraded === '1') {\n return 'graded';\n } else if (isGraded === '0') {\n return 'ungraded';\n }\n return 'all';\n },\n getDelocalizedTaskLink: function() {\n return delocalizeLink(taskSelectionInput.value);\n },\n setMultiSelection: setMultiSelection,\n hasMultiTasks: function() {\n const tasksField = document.getElementsByName('mumie_multi_tasks')[0];\n return tasksField && !!tasksField.value;\n },\n submitMultiTasks: submitMultiTasks,\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 * Show or hide per-task \"Working period: not Deadline\" warnings based on whether the duedate property is selected.\n */\n function updateNoDuedateWarnings() {\n const duedateSelected = Array.from(propertySelectionInputs)\n .some(checkbox => checkbox.value === 'duedate' && checkbox.checked);\n document.querySelectorAll('.mumie-form-working-period-not-duedate-warning').forEach(function(elem) {\n elem.style.display = duedateSelected ? '' : 'none';\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 updateNoDuedateWarnings();\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 const worksheetController = (function() {\n const worksheetElement = document.getElementById(\"id_mumie_worksheet\");\n return {\n setWorksheet: function(worksheet) {\n if (worksheet) {\n worksheetElement.setAttribute(\"value\", JSON.stringify(worksheet));\n } else {\n worksheetElement.removeAttribute(\"value\");\n }\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(contextIdParam, prbSelectorUrl, lang, sectionParam) {\n lmsSelectorUrl = prbSelectorUrl;\n systemLanguage = lang;\n contextId = contextIdParam;\n section = sectionParam;\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();\n multiTaskEditController.init();\n problemSelectorController.init();\n durationController.init();\n }\n if (addServerButton) {\n require(['auth_mumie/mumie_server_config'], function(MumieServer) {\n MumieServer.init(addServerButton, contextId);\n });\n }\n\n const submitButton = document.getElementById('id_submitbutton');\n const form = submitButton && submitButton.closest('form');\n if (form) {\n let cancelClicked = false;\n const cancelButton = document.getElementById('id_cancel');\n if (cancelButton) {\n cancelButton.addEventListener('click', function() {\n cancelClicked = true;\n });\n }\n form.addEventListener('submit', function(e) {\n if (cancelClicked) {\n cancelClicked = false;\n return;\n }\n if (taskController.hasMultiTasks()) {\n e.preventDefault();\n taskController.submitMultiTasks();\n }\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","contextId","section","durationController","durationSelector","gradedElem","isUngraded","value","updateDurationElements","setAttribute","removeAttribute","style","display","duedatePropRow","querySelector","_document$querySelect","closest","show","duedatePropertyCheckbox","checked","dispatchEvent","Event","init","onchange","window","addEventListener","setDurationElements","setGradedElemValue","isGraded","getGradedElemValue","serverController","serverStructure","serverDropDown","structure","getSelectedServer","selectedServerName","options","selectedIndex","text","find","server","name","disable","disabled","elem","firstChild","removeChild","removeChildElems","problemSelectorController","problemSelectorButton","multiProblemSelectorButton","problemSelectorWindow","mumieOrg","sendResponse","response","postMessage","JSON","stringify","sendSuccess","message","success","addMessageListener","event","origin","importObj","parse","data","Array","isArray","taskController","setMultiSelection","applyPickerPayloadToForm","require","str","notification","get_strings","component","done","s","addNotification","type","fail","exception","focus","error","sendFailure","buildURL","multiSelect","gradingType","getGradingType","selectedServer","urlprefix","useSSO","shouldUseSSO","base","encodeURIComponent","langController","getSelectedLanguage","location","selection","getDelocalizedTaskLink","problemSelectorUrl","selectedServerUrl","URL","onclick","open","onclose","e","preventDefault","payload","worksheet","courseController","setCourse","path_to_coursefile","setLanguage","language","setSelection","link","setIsGraded","worksheetController","setWorksheet","courseNameElem","courseFileElem","updateCourseName","selectedCourse","getSelectedCourse","selectedLanguage","translation","_selectedCourse$name$","courses","course","coursefile","courseFile","languageElem","lang","taskSelectionInput","nameElem","taskDisplayElement","updateTaskDisplayElement","localizedLink","updateTaskUri","localizeLink","tasks","tasksField","summary","taskListItems","map","task","taskListItem","createElement","textContent","innerHTML","summaryHeading","taskList","Str","get_string","length","then","headingText","classList","add","forEach","appendChild","nameField","taskDisplayElem","nameFieldContainer","querySelectorAll","requiredIndicator","requiredLegend","updateName","updateGradeEditability","includes","split","hasMultiTasks","submitMultiTasks","courseId","_document$getElements","submitButton","form","tasksFormData","disabledFields","from","field","omit","FormData","filter","_ref","key","_ref2","join","serializeFormFields","Ajax","call","methodname","args","contextid","parseInt","tasksformdata","href","M","cfg","wwwroot","alert","multiTaskEditController","propertySelectionInputs","selectedTaskProperties","selectedTaskProp","taskSelectionInputs","selectedTasks","selectedTaskIds","sectionInputs","setPropertySelectionListeners","checkbox","push","duedateSelected","some","updateNoDuedateWarnings","sectionCheckbox","taskCheckbox","array","element","getAttribute","worksheetElement","disableDropDownMenus","errorKey","contextIdParam","prbSelectorUrl","sectionParam","isEdit","MumieServer","cancelClicked","cancelButton"],"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 ba494de6..0839a900 100644 --- a/amd/src/mod_form.js +++ b/amd/src/mod_form.js @@ -5,6 +5,7 @@ define(['jquery', 'core/templates', 'auth_mumie/mumie_server_config', 'core/ajax let lmsSelectorUrl; let systemLanguage; let contextId; + let section; const durationController = (function() { @@ -496,7 +497,6 @@ define(['jquery', 'core/templates', 'auth_mumie/mumie_server_config', 'core/ajax function submitMultiTasks() { const tasksField = document.getElementsByName('mumie_multi_tasks')[0]; const courseId = document.getElementsByName('course')[0]?.value; - const section = parseInt(new URLSearchParams(window.location.search).get('section') || 0); const submitButton = document.getElementById('id_submitbutton'); const form = submitButton && submitButton.closest('form'); const tasks = JSON.parse(tasksField.value); @@ -717,10 +717,11 @@ define(['jquery', 'core/templates', 'auth_mumie/mumie_server_config', 'core/ajax } return { - init: function(contextIdParam, prbSelectorUrl, lang) { + init: function(contextIdParam, prbSelectorUrl, lang, sectionParam) { lmsSelectorUrl = prbSelectorUrl; systemLanguage = lang; contextId = contextIdParam; + section = sectionParam; const isEdit = document.getElementById("id_name").getAttribute('value'); const serverStructure = JSON.parse(document.getElementsByName('mumie_server_structure')[0].value); if (isEdit && !serverConfigExists()) { diff --git a/mod_form.php b/mod_form.php index 79175dc0..26174c94 100644 --- a/mod_form.php +++ b/mod_form.php @@ -72,10 +72,22 @@ public function definition(): void { $context = context_course::instance($COURSE->id); $this->disable_grade_rules(); + // Resolve the target section number the same way modedit.php does. + // The multi-problem button is only enabled when adding (not editing), + // so URL params are populated; on Moodle 5.1+ the URL prefers sectionid, + // on older versions it uses section. + $sectionid = optional_param('sectionid', null, PARAM_INT); + $sectionnum = optional_param('section', 0, PARAM_INT); + if (empty($sectionnum) && !empty($sectionid)) { + $sectionnum = (int) get_fast_modinfo($COURSE) + ->get_section_info_by_id($sectionid, MUST_EXIST)->sectionnum; + } + $jsparams = [ json_encode($context->id), get_config('auth_mumie', 'mumie_problem_selector_url'), $USER->lang, + $sectionnum, ]; $PAGE->requires->js_call_amd('mod_mumie/mod_form', 'init', $jsparams); } From c3cb3287295a5cc6feaaf0cd30078aeb8ab7a57a Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Mon, 29 Jun 2026 12:15:09 +0200 Subject: [PATCH 099/101] change required moodle version in changelog --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 736a6a2b..c4a0d11c 100644 --- a/changelog.md +++ b/changelog.md @@ -10,7 +10,7 @@ All important changes to this plugin will be documented in this file. - SSO when opening the Multi Problem Selector for the Problem Pool ### Changed -- Plugin now requires Moodle 4.3 +- Plugin now requires Moodle 4.3 or higher - Support Moodle 5.2 - Multi Problem Selector now creates MUMIE Tasks via form submission instead of drag-and-drop - Settings configured on the form (points, deadline, container, etc.) are now applied to all tasks created via the Multi Problem Selector From 4c5daa834103a37118046c7b973146d6068837ed Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Mon, 29 Jun 2026 13:21:36 +0200 Subject: [PATCH 100/101] prepare release --- changelog.md | 2 +- db/upgrade.php | 4 ++-- version.php | 7 +++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/changelog.md b/changelog.md index c4a0d11c..26edf98b 100644 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,7 @@ All important changes to this plugin will be documented in this file. -## TODO +## [1.10.0] - 2026-06-29 ### Added - Teachers can now apply the deadline setting to multiple MUMIE Tasks at once using the multi-edit feature - Tasks without a 'Deadline' working period show a warning when deadline transfer is selected diff --git a/db/upgrade.php b/db/upgrade.php index 4b69ff09..36d1bca5 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -91,9 +91,9 @@ function xmldb_mumie_upgrade($oldversion) { addfieldifmissing('mumie', 'timelimit', XMLDB_TYPE_INTEGER, '10', null, false, null, null, null); upgrade_plugin_savepoint(true, 2025031200, 'mod', 'mumie'); } - if ($oldversion < 2026062300) { + if ($oldversion < 2026062900) { dropfieldifexists('mumie', 'completionpass'); - upgrade_plugin_savepoint(true, 2026062300, 'mod', 'mumie'); + upgrade_plugin_savepoint(true, 2026062900, 'mod', 'mumie'); } return true; diff --git a/version.php b/version.php index cf029694..c46f952d 100644 --- a/version.php +++ b/version.php @@ -25,12 +25,11 @@ defined('MOODLE_INTERNAL') || die; -// todo: before release, the version in /db/upgrade.php should match the updated plugin version -$plugin->version = 2026062300; // The current module version (Date: YYYYMMDDXX). +$plugin->version = 2026062900; // The current module version (Date: YYYYMMDDXX). $plugin->component = 'mod_mumie'; // Full name of the plugin (used for diagnostics). $plugin->requires = 2023100900; // 4.3 -$plugin->release = "v1.9.1"; +$plugin->release = "v1.10.0"; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = [ - 'auth_mumie' => 2025051500, + 'auth_mumie' => 2026062900, ]; From 4f2dfec8229dea391702e5eb59b8e5aba5feb360 Mon Sep 17 00:00:00 2001 From: Dung Pham Date: Mon, 29 Jun 2026 13:24:21 +0200 Subject: [PATCH 101/101] cleanup resolving merge conflicts --- classes/mumie_dndupload_processor.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 classes/mumie_dndupload_processor.php diff --git a/classes/mumie_dndupload_processor.php b/classes/mumie_dndupload_processor.php deleted file mode 100644 index e69de29b..00000000