diff --git a/mod/bigbluebuttonbn/amd/build/modform.min.js b/mod/bigbluebuttonbn/amd/build/modform.min.js index 044b60524d3..03930d0e8c2 100644 --- a/mod/bigbluebuttonbn/amd/build/modform.min.js +++ b/mod/bigbluebuttonbn/amd/build/modform.min.js @@ -1,2 +1,2 @@ -define ("mod_bigbluebuttonbn/modform",["exports","core/str","core/notification","core/templates"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;c=e(c);d=e(d);function e(a){return a&&a.__esModule?a:{default:a}}function f(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function g(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var i=a.apply(b,c);function g(a){f(i,d,e,g,h,"next",a)}function h(a){f(i,d,e,g,h,"throw",a)}g(void 0)})}}var h={instanceTypeSelection:function instanceTypeSelection(){return document.querySelector("select#id_type")},instanceTypeProfiles:function instanceTypeProfiles(){return document.querySelector("[data-profile-types]")},participantData:function participantData(){return document.querySelector("[data-participant-data]")},participantList:function participantList(){return document.getElementsByName("participants")[0]},participantTable:function participantTable(){return document.getElementById("participant_list_table")},participantSelectionType:function participantSelectionType(){return document.getElementsByName("bigbluebuttonbn_participant_selection_type")[0]},participantSelection:function participantSelection(){return document.getElementsByName("bigbluebuttonbn_participant_selection")[0]},participantAddButton:function participantAddButton(){return document.getElementsByName("bigbluebuttonbn_participant_selection_add")[0]}};a.init=function init(a){var b=h.instanceTypeSelection(),c=JSON.parse(h.instanceTypeProfiles().dataset.profileTypes),d=a.instanceTypeDefault;if(null!==b&&-1!==b.selectedIndex){d=b.options[b.selectedIndex].value}var f=function(a,b){var d=c[a].features;return-1!==d.indexOf(b)};i(d,f);b.addEventListener("change",function(a){i(a.target.value,f)});h.participantSelectionType().addEventListener("change",function(a){var b=a.target;q(b)});h.participantAddButton().addEventListener("click",function(a){a.stopPropagation();a.preventDefault();p()});j()};var i=function(a,b){var c=b(a,"all"),d=function(a,b){var c=document.querySelector("#"+a);if(!c){return}if(b){c.style.display="block";return}c.style.display="none"},e=function(a,b){var c=document.querySelector("#"+a);if(!c){return}var d=c.closest("div").closest("div");if(b){d.style.display="block";return}d.style.display="none"},f=function(a,b){var c=document.querySelector("#fgroup_id_"+a);if(!c){return}if(b){c.classList.remove("hidden");return}c.classList.add("hidden")};d("id_room",c||b(a,"showroom"));e("id_record",c||b(a,"showroom"));d("id_recordings",c||b(a,"showrecordings"));e("id_recordings_imported",c||b(a,"showrecordings"));d("id_preuploadpresentation",c||b(a,"preuploadpresentation"));d("id_permissions",c||b(a,"permissions"));d("id_schedule",c||b(a,"schedule"));d("id_modstandardelshdr",c||b(a,"modstandardelshdr"));d("id_availabilityconditionsheader",c||b(a,"availabilityconditionsheader"));d("id_tagshdr",c||b(a,"tagshdr"));d("id_competenciessection",c||b(a,"competenciessection"));f("completionattendancegroup",c||b(a,"completionattendance"));f("completionengagementgroup",c||b(a,"completionengagement"))},j=function(){var a=JSON.parse(h.participantData().dataset.participantData),b=m();b.forEach(function(b){var c=b.selectiontype,d=b.selectionid,e=b.role;if("all"===b.selectiontype||"undefined"!=typeof a[b.selectiontype].children[b.selectionid]){k(c,d,e,!0).then()}})},k=function(){var a=g(regeneratorRuntime.mark(function a(e,f,g,i){var j,k,l,m,p,q,r,s,t,u,v;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:j=JSON.parse(h.participantData().dataset.participantData);a.next=3;return(0,b.get_string)("mod_form_field_participant_bbb_role_viewer","mod_bigbluebuttonbn");case 3:k=a.sent;a.next=6;return(0,b.get_string)("mod_form_field_participant_bbb_role_moderator","mod_bigbluebuttonbn");case 6:l=a.sent;m={viewer:{id:"viewer",label:k},moderator:{id:"moderator",label:l}};m[g].isselected=!0;a.prev=9;p=document.querySelector("#participant_list_table tbody");q={selectiontypevalue:e,selectionvalue:f,participanttype:j[e].name,participantvalue:"all"!==e?j[e].children[f].name:null,roles:Object.values(m),canRemove:i};a.next=14;return d.default.renderForPromise("mod_bigbluebuttonbn/participant_form_add",q);case 14:r=a.sent;s=r.html;t=r.js;u=d.default.appendNodeContents(p,s,t)[0];u.querySelector(".participant-select").addEventListener("change",function(){o(e,f)});v=u.querySelector(".remove-button");if(v){v.addEventListener("click",function(){n(e,f)})}a.next=26;break;case 23:a.prev=23;a.t0=a["catch"](9);c.default.exception(a.t0);case 26:case"end":return a.stop();}}},a,null,[[9,23]])}));return function(){return a.apply(this,arguments)}}(),l=function(a){var b=h.participantList();b.value=JSON.stringify(a)},m=function(){var a=h.participantList().value;if(a){return JSON.parse(a)}return[]},n=function(a,b){for(var c=m(),d="participant_list_tr_"+a+"-"+b,e=h.participantTable(),f=""===b?null:b,g=0;g.\n\n/**\n * JS for the mod_form page on mod_bigbluebuttonbn plugin.\n *\n * @module mod_bigbluebuttonbn/mod_form\n * @copyright 2021 Blindside Networks Inc\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Templates from \"core/templates\";\n\n/**\n * Get all selectors in one place.\n *\n */\nconst ELEMENT_SELECTOR = {\n instanceTypeSelection: () => document.querySelector('select#id_type'),\n instanceTypeProfiles: () => document.querySelector('[data-profile-types]'),\n participantData: () => document.querySelector('[data-participant-data]'),\n participantList: () => document.getElementsByName('participants')[0],\n participantTable: () => document.getElementById('participant_list_table'),\n participantSelectionType: () => document.getElementsByName('bigbluebuttonbn_participant_selection_type')[0],\n participantSelection: () => document.getElementsByName('bigbluebuttonbn_participant_selection')[0],\n participantAddButton: () => document.getElementsByName('bigbluebuttonbn_participant_selection_add')[0],\n};\n/**\n * Initialise the moodle form code.\n *\n * This will help hide or show items depending on the selection of the instance type.\n *\n * @method init\n * @param {object} info\n */\nexport const init = (info) => {\n const selectedType = ELEMENT_SELECTOR.instanceTypeSelection();\n const instanceTypeProfiles = JSON.parse(ELEMENT_SELECTOR.instanceTypeProfiles().dataset.profileTypes);\n\n let profileType = info.instanceTypeDefault;\n if (selectedType !== null && selectedType.selectedIndex !== -1) {\n profileType = selectedType.options[selectedType.selectedIndex].value;\n }\n\n const isFeatureEnabled = (profileType, feature) => {\n const features = instanceTypeProfiles[profileType].features;\n return (features.indexOf(feature) !== -1);\n };\n applyInstanceTypeProfile(profileType, isFeatureEnabled);\n\n // Change form visible fields depending on the selection.\n selectedType.addEventListener('change', (e) => {\n applyInstanceTypeProfile(e.target.value, isFeatureEnabled);\n });\n\n ELEMENT_SELECTOR.participantSelectionType().addEventListener('change', (e) => {\n const currentTypeSelect = e.target;\n updateSelectionFromType(currentTypeSelect);\n });\n\n ELEMENT_SELECTOR.participantAddButton().addEventListener('click', (e) => {\n e.stopPropagation();\n e.preventDefault();\n participantAddFromCurrentSelection();\n });\n\n participantListInit();\n};\n\n/**\n * Show or hide form element depending on the selected profile\n *\n * @param {string} profileType\n * @param {function} isFeatureEnabled\n */\nconst applyInstanceTypeProfile = (profileType, isFeatureEnabled) => {\n let showAll = isFeatureEnabled(profileType, 'all');\n const showFieldset = (id, show) => {\n // Show room settings validation.\n const node = document.querySelector('#' + id);\n if (!node) {\n return;\n }\n if (show) {\n node.style.display = 'block';\n return;\n }\n node.style.display = 'none';\n };\n const showInput = (id, show) => {\n // Show room settings validation.\n const node = document.querySelector('#' + id);\n if (!node) {\n return;\n }\n var ancestor = node.closest('div').closest('div');\n if (show) {\n ancestor.style.display = 'block';\n return;\n }\n ancestor.style.display = 'none';\n };\n const showFormGroup = (id, show) => {\n // Show room settings validation.\n const node = document.querySelector('#fgroup_id_' + id);\n if (!node) {\n return;\n }\n if (show) {\n node.classList.remove('hidden');\n return;\n }\n node.classList.add('hidden');\n };\n // Show room settings validation.\n showFieldset('id_room', showAll ||\n isFeatureEnabled(profileType, 'showroom'));\n showInput('id_record', showAll ||\n isFeatureEnabled(profileType, 'showroom'));\n // Show recordings settings validation.\n showFieldset('id_recordings', showAll ||\n isFeatureEnabled(profileType, 'showrecordings'));\n // Show recordings imported settings validation.\n showInput('id_recordings_imported', showAll ||\n isFeatureEnabled(profileType, 'showrecordings'));\n // Preuploadpresentation feature validation.\n showFieldset('id_preuploadpresentation', showAll ||\n isFeatureEnabled(profileType, 'preuploadpresentation'));\n // Participants feature validation.\n showFieldset('id_permissions', showAll ||\n isFeatureEnabled(profileType, 'permissions'));\n // Schedule feature validation.\n showFieldset('id_schedule', showAll ||\n isFeatureEnabled(profileType, 'schedule'));\n // Common module settings validation.\n showFieldset('id_modstandardelshdr', showAll ||\n isFeatureEnabled(profileType, 'modstandardelshdr'));\n // Restrict access validation.\n showFieldset('id_availabilityconditionsheader', showAll ||\n isFeatureEnabled(profileType, 'availabilityconditionsheader'));\n // Tags validation.\n showFieldset('id_tagshdr', showAll || isFeatureEnabled(profileType, 'tagshdr'));\n // Competencies validation.\n showFieldset('id_competenciessection', showAll ||\n isFeatureEnabled(profileType, 'competenciessection'));\n // Completion validation.\n showFormGroup('completionattendancegroup', showAll ||\n isFeatureEnabled(profileType, 'completionattendance'));\n // Completion validation.\n showFormGroup('completionengagementgroup', showAll ||\n isFeatureEnabled(profileType, 'completionengagement'));\n};\n\n/**\n * Init the participant list\n */\nconst participantListInit = () => {\n const participantData = JSON.parse(ELEMENT_SELECTOR.participantData().dataset.participantData);\n const participantList = getParticipantList();\n participantList.forEach(participant => {\n const selectionTypeValue = participant.selectiontype;\n const selectionValue = participant.selectionid;\n const selectionRole = participant.role;\n if (participant.selectiontype === 'all' ||\n typeof participantData[participant.selectiontype].children[participant.selectionid] !== 'undefined') {\n // Add it to the form, but don't add the delete button if it is the first item.\n participantAddToForm(selectionTypeValue, selectionValue, selectionRole, true).then();\n }\n });\n};\n\n/**\n * Add rows to the participant list depending on the current selection.\n *\n * @param {string} selectionTypeValue\n * @param {string} selectionValue\n * @param {string} selectedRole\n * @param {boolean} canRemove\n * @returns {Promise}\n */\nconst participantAddToForm = async(selectionTypeValue, selectionValue, selectedRole, canRemove) => {\n const participantData = JSON.parse(ELEMENT_SELECTOR.participantData().dataset.participantData);\n const sviewer = await getString('mod_form_field_participant_bbb_role_viewer', 'mod_bigbluebuttonbn');\n const smoderator = await getString('mod_form_field_participant_bbb_role_moderator', 'mod_bigbluebuttonbn');\n let roles = {\n viewer: {'id': 'viewer', label: sviewer},\n moderator: {'id': 'moderator', label: smoderator}\n };\n roles[selectedRole].isselected = true;\n try {\n const listTable = document.querySelector('#participant_list_table tbody');\n const templateContext = {\n 'selectiontypevalue': selectionTypeValue,\n 'selectionvalue': selectionValue,\n 'participanttype': participantData[selectionTypeValue].name,\n 'participantvalue':\n (selectionTypeValue !== 'all') ?\n participantData[selectionTypeValue].children[selectionValue].name : null,\n 'roles': Object.values(roles),\n 'canRemove': canRemove\n };\n const {html, js} = await Templates.renderForPromise('mod_bigbluebuttonbn/participant_form_add', templateContext);\n const newNode = Templates.appendNodeContents(listTable, html, js)[0];\n newNode.querySelector('.participant-select').addEventListener('change', () => {\n participantListRoleUpdate(selectionTypeValue, selectionValue);\n });\n // Now add the callbacks: participantListRoleUpdate() and participantRemove().\n const removeNode = newNode.querySelector('.remove-button');\n if (removeNode) {\n removeNode\n .addEventListener('click', () => {\n participantRemove(selectionTypeValue, selectionValue);\n });\n }\n\n } catch (e) {\n Notification.exception(e);\n }\n};\n/*\n\n */\n\n/**\n * Update the related form element with the list value.\n *\n * @param {object} list\n */\nconst participantListUpdate = (list) => {\n const participantList = ELEMENT_SELECTOR.participantList();\n participantList.value = JSON.stringify(list);\n};\n\n/**\n *\n * @returns {any}\n */\nconst getParticipantList = () => {\n const participantListValue = ELEMENT_SELECTOR.participantList().value;\n if (participantListValue) {\n return JSON.parse(participantListValue);\n }\n return [];\n};\n\n/**\n * Remove participant both in the table/form and in the form element.\n *\n * @param {string} selectionTypeValue\n * @param {string} selectionValue\n */\nconst participantRemove = (selectionTypeValue, selectionValue) => {\n const pList = getParticipantList();\n const id = 'participant_list_tr_' + selectionTypeValue + '-' + selectionValue;\n const participantListTable = ELEMENT_SELECTOR.participantTable();\n const selectionid = (selectionValue === '' ? null : selectionValue);\n for (let i = 0; i < pList.length; i++) {\n if (pList[i].selectiontype === selectionTypeValue &&\n pList[i].selectionid === selectionid) {\n pList.splice(i, 1);\n }\n }\n // Remove from the form.\n for (let i = 0; i < participantListTable.rows.length; i++) {\n if (participantListTable.rows[i].id === id) {\n participantListTable.deleteRow(i);\n }\n }\n // Update value in the form.\n participantListUpdate(pList);\n};\n\n/**\n * Role update\n *\n * @param {string} type\n * @param {string} id\n */\nconst participantListRoleUpdate = (type, id) => {\n // Update in memory.\n const participantListRoleSelection = document.querySelector(`#participant_list_tr_${type}-${id} .participant-select`);\n const pList = getParticipantList();\n\n for (var i = 0; i < pList.length; i++) {\n if (pList[i].selectiontype === type &&\n pList[i].selectionid === (id === '' ? null : parseInt(id))) {\n pList[i].role = participantListRoleSelection.value;\n }\n }\n // Update in the form.\n participantListUpdate(pList);\n};\n\n/**\n * Add participant from the currently selected options\n */\nconst participantAddFromCurrentSelection = () => {\n let selectionType = ELEMENT_SELECTOR.participantSelectionType();\n let selection = ELEMENT_SELECTOR.participantSelection();\n const pList = getParticipantList();\n // Lookup to see if it has been added already.\n for (var i = 0; i < pList.length; i++) {\n if (pList[i].selectiontype === selectionType.value &&\n pList[i].selectionid === selection.value) {\n return;\n }\n }\n pList.push({\n \"selectiontype\": selectionType.value,\n \"selectionid\": selection.value,\n \"role\": \"viewer\"\n });\n // Add it to the form.\n participantAddToForm(selectionType.value, selection.value, 'viewer', true).then();\n // Update in the form.\n participantListUpdate(pList);\n};\n\n/**\n * Update selectable options when changing types\n *\n * @param {HTMLNode} currentTypeSelect\n */\nconst updateSelectionFromType = (currentTypeSelect) => {\n const createNewOption = (selectItem, label, value) => {\n const option = document.createElement('option');\n option.text = label;\n option.value = value;\n\n selectItem.add(option);\n };\n\n const participantData = JSON.parse(ELEMENT_SELECTOR.participantData().dataset.participantData);\n // Clear all selection items.\n const participantSelect = ELEMENT_SELECTOR.participantSelection();\n while (participantSelect.firstChild) {\n participantSelect.removeChild(participantSelect.firstChild);\n }\n // Add options depending on the selection.\n if (currentTypeSelect.selectedIndex !== -1) {\n const options = Object.values(participantData[currentTypeSelect.value].children);\n options.forEach(option => {\n createNewOption(participantSelect, option.name, option.id);\n });\n\n if (currentTypeSelect.value === 'all') {\n createNewOption(participantSelect, '---------------', 'all');\n participantSelect.disabled = true;\n } else {\n participantSelect.disabled = false;\n }\n }\n};\n"],"file":"modform.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/modform.js"],"names":["ELEMENT_SELECTOR","instanceTypeSelection","document","querySelector","instanceTypeProfiles","participantData","participantList","getElementsByName","participantTable","getElementById","participantSelectionType","participantSelection","participantAddButton","init","info","selectedType","JSON","parse","dataset","profileTypes","profileType","instanceTypeDefault","selectedIndex","options","value","isFeatureEnabled","feature","features","indexOf","applyInstanceTypeProfile","addEventListener","e","target","currentTypeSelect","updateSelectionFromType","stopPropagation","preventDefault","participantAddFromCurrentSelection","participantListInit","showAll","showFieldset","id","show","node","style","display","showInput","ancestor","closest","showFormGroup","classList","remove","add","getParticipantList","forEach","participant","selectionTypeValue","selectiontype","selectionValue","selectionid","selectionRole","role","children","participantAddToForm","then","selectedRole","canRemove","sviewer","smoderator","roles","viewer","label","moderator","isselected","listTable","templateContext","name","Object","values","Templates","renderForPromise","html","js","newNode","appendNodeContents","participantListRoleUpdate","removeNode","participantRemove","Notification","exception","participantListUpdate","list","stringify","participantListValue","pList","participantListTable","i","length","splice","rows","deleteRow","type","participantListRoleSelection","selectionType","selection","push","createNewOption","selectItem","option","createElement","text","participantSelect","firstChild","removeChild","disabled"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * JS for the mod_form page on mod_bigbluebuttonbn plugin.\n *\n * @module mod_bigbluebuttonbn/mod_form\n * @copyright 2021 Blindside Networks Inc\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Templates from \"core/templates\";\n\n/**\n * Get all selectors in one place.\n *\n */\nconst ELEMENT_SELECTOR = {\n instanceTypeSelection: () => document.querySelector('select#id_type'),\n instanceTypeProfiles: () => document.querySelector('[data-profile-types]'),\n participantData: () => document.querySelector('[data-participant-data]'),\n participantList: () => document.getElementsByName('participants')[0],\n participantTable: () => document.getElementById('participant_list_table'),\n participantSelectionType: () => document.getElementsByName('bigbluebuttonbn_participant_selection_type')[0],\n participantSelection: () => document.getElementsByName('bigbluebuttonbn_participant_selection')[0],\n participantAddButton: () => document.getElementsByName('bigbluebuttonbn_participant_selection_add')[0],\n};\n/**\n * Initialise the moodle form code.\n *\n * This will help hide or show items depending on the selection of the instance type.\n *\n * @method init\n * @param {object} info\n */\nexport const init = (info) => {\n const selectedType = ELEMENT_SELECTOR.instanceTypeSelection();\n const instanceTypeProfiles = JSON.parse(ELEMENT_SELECTOR.instanceTypeProfiles().dataset.profileTypes);\n\n let profileType = info.instanceTypeDefault;\n if (selectedType !== null && selectedType.selectedIndex !== -1) {\n profileType = selectedType.options[selectedType.selectedIndex].value;\n }\n\n const isFeatureEnabled = (profileType, feature) => {\n const features = instanceTypeProfiles[profileType].features;\n return (features.indexOf(feature) !== -1);\n };\n applyInstanceTypeProfile(profileType, isFeatureEnabled);\n\n // Change form visible fields depending on the selection.\n selectedType.addEventListener('change', (e) => {\n applyInstanceTypeProfile(e.target.value, isFeatureEnabled);\n });\n\n ELEMENT_SELECTOR.participantSelectionType().addEventListener('change', (e) => {\n const currentTypeSelect = e.target;\n updateSelectionFromType(currentTypeSelect);\n });\n\n ELEMENT_SELECTOR.participantAddButton().addEventListener('click', (e) => {\n e.stopPropagation();\n e.preventDefault();\n participantAddFromCurrentSelection();\n });\n\n participantListInit();\n};\n\n/**\n * Show or hide form element depending on the selected profile\n *\n * @param {string} profileType\n * @param {function} isFeatureEnabled\n */\nconst applyInstanceTypeProfile = (profileType, isFeatureEnabled) => {\n let showAll = isFeatureEnabled(profileType, 'all');\n const showFieldset = (id, show) => {\n // Show room settings validation.\n const node = document.querySelector('#' + id);\n if (!node) {\n return;\n }\n if (show) {\n node.style.display = 'block';\n return;\n }\n node.style.display = 'none';\n };\n const showInput = (id, show) => {\n // Show room settings validation.\n const node = document.querySelector('#' + id);\n if (!node) {\n return;\n }\n var ancestor = node.closest('div').closest('div');\n if (show) {\n ancestor.style.display = 'block';\n return;\n }\n ancestor.style.display = 'none';\n };\n const showFormGroup = (id, show) => {\n // Show room settings validation.\n const node = document.querySelector('#fgroup_id_' + id);\n if (!node) {\n return;\n }\n if (show) {\n node.classList.remove('hidden');\n return;\n }\n node.classList.add('hidden');\n };\n // Show room settings validation.\n showFieldset('id_room', showAll ||\n isFeatureEnabled(profileType, 'showroom'));\n showInput('id_record', showAll ||\n isFeatureEnabled(profileType, 'showroom'));\n // Show recordings settings validation.\n showFieldset('id_recordings', showAll ||\n isFeatureEnabled(profileType, 'showrecordings'));\n // Show recordings imported settings validation.\n showInput('id_recordings_imported', showAll ||\n isFeatureEnabled(profileType, 'showrecordings'));\n // Preuploadpresentation feature validation.\n showFieldset('id_preuploadpresentation', showAll ||\n isFeatureEnabled(profileType, 'preuploadpresentation'));\n // Participants feature validation.\n showFieldset('id_permissions', showAll ||\n isFeatureEnabled(profileType, 'permissions'));\n // Schedule feature validation.\n showFieldset('id_schedule', showAll ||\n isFeatureEnabled(profileType, 'schedule'));\n // Common module settings validation.\n showFieldset('id_modstandardelshdr', showAll ||\n isFeatureEnabled(profileType, 'modstandardelshdr'));\n // Restrict access validation.\n showFieldset('id_availabilityconditionsheader', showAll ||\n isFeatureEnabled(profileType, 'availabilityconditionsheader'));\n // Tags validation.\n showFieldset('id_tagshdr', showAll || isFeatureEnabled(profileType, 'tagshdr'));\n // Competencies validation.\n showFieldset('id_competenciessection', showAll ||\n isFeatureEnabled(profileType, 'competenciessection'));\n // Completion validation.\n showFormGroup('completionattendancegroup', showAll ||\n isFeatureEnabled(profileType, 'completionattendance'));\n // Completion validation.\n showFormGroup('completionengagementgroup', showAll ||\n isFeatureEnabled(profileType, 'completionengagement'));\n};\n\n/**\n * Init the participant list\n */\nconst participantListInit = () => {\n const participantData = JSON.parse(ELEMENT_SELECTOR.participantData().dataset.participantData);\n const participantList = getParticipantList();\n participantList.forEach(participant => {\n const selectionTypeValue = participant.selectiontype;\n const selectionValue = participant.selectionid;\n const selectionRole = participant.role;\n if (participant.selectiontype === 'all' ||\n typeof participantData[participant.selectiontype].children[participant.selectionid] !== 'undefined') {\n // Add it to the form, but don't add the delete button if it is the first item.\n participantAddToForm(selectionTypeValue, selectionValue, selectionRole, true).then();\n }\n });\n};\n\n/**\n * Add rows to the participant list depending on the current selection.\n *\n * @param {string} selectionTypeValue\n * @param {string} selectionValue\n * @param {string} selectedRole\n * @param {boolean} canRemove\n * @returns {Promise}\n */\nconst participantAddToForm = async(selectionTypeValue, selectionValue, selectedRole, canRemove) => {\n const participantData = JSON.parse(ELEMENT_SELECTOR.participantData().dataset.participantData);\n const sviewer = await getString('mod_form_field_participant_bbb_role_viewer', 'mod_bigbluebuttonbn');\n const smoderator = await getString('mod_form_field_participant_bbb_role_moderator', 'mod_bigbluebuttonbn');\n let roles = {\n viewer: {'id': 'viewer', label: sviewer},\n moderator: {'id': 'moderator', label: smoderator}\n };\n roles[selectedRole].isselected = true;\n try {\n const listTable = document.querySelector('#participant_list_table tbody');\n const templateContext = {\n 'selectiontypevalue': selectionTypeValue,\n 'selectionvalue': selectionValue,\n 'participanttype': participantData[selectionTypeValue].name,\n 'participantvalue':\n (selectionTypeValue !== 'all') ?\n participantData[selectionTypeValue].children[selectionValue].name : null,\n 'roles': Object.values(roles),\n 'canRemove': canRemove\n };\n const {html, js} = await Templates.renderForPromise('mod_bigbluebuttonbn/participant_form_add', templateContext);\n const newNode = Templates.appendNodeContents(listTable, html, js)[0];\n newNode.querySelector('.participant-select').addEventListener('change', () => {\n participantListRoleUpdate(selectionTypeValue, selectionValue);\n });\n // Now add the callbacks: participantListRoleUpdate() and participantRemove().\n const removeNode = newNode.querySelector('.remove-button');\n if (removeNode) {\n removeNode\n .addEventListener('click', () => {\n participantRemove(selectionTypeValue, selectionValue);\n });\n }\n\n } catch (e) {\n Notification.exception(e);\n }\n};\n/*\n\n */\n\n/**\n * Update the related form element with the list value.\n *\n * @param {object} list\n */\nconst participantListUpdate = (list) => {\n const participantList = ELEMENT_SELECTOR.participantList();\n participantList.value = JSON.stringify(list);\n};\n\n/**\n *\n * @returns {any}\n */\nconst getParticipantList = () => {\n const participantListValue = ELEMENT_SELECTOR.participantList().value;\n if (participantListValue) {\n return JSON.parse(participantListValue);\n }\n return [];\n};\n\n/**\n * Remove participant both in the table/form and in the form element.\n *\n * @param {string} selectionTypeValue\n * @param {string} selectionValue\n */\nconst participantRemove = (selectionTypeValue, selectionValue) => {\n const pList = getParticipantList();\n const id = 'participant_list_tr_' + selectionTypeValue + '-' + selectionValue;\n const participantListTable = ELEMENT_SELECTOR.participantTable();\n const selectionid = (selectionValue === '' ? null : selectionValue);\n for (let i = 0; i < pList.length; i++) {\n if (pList[i].selectiontype === selectionTypeValue &&\n pList[i].selectionid === selectionid) {\n pList.splice(i, 1);\n }\n }\n // Remove from the form.\n for (let i = 0; i < participantListTable.rows.length; i++) {\n if (participantListTable.rows[i].id === id) {\n participantListTable.deleteRow(i);\n }\n }\n // Update value in the form.\n participantListUpdate(pList);\n};\n\n/**\n * Role update\n *\n * @param {string} type\n * @param {string} id\n */\nconst participantListRoleUpdate = (type, id) => {\n // Update in memory.\n const participantListRoleSelection = document.querySelector(`#participant_list_tr_${type}-${id} .participant-select`);\n const pList = getParticipantList();\n\n for (var i = 0; i < pList.length; i++) {\n if (pList[i].selectiontype === type && pList[i].selectionid === id) {\n pList[i].role = participantListRoleSelection.value;\n }\n }\n // Update in the form.\n participantListUpdate(pList);\n};\n\n/**\n * Add participant from the currently selected options\n */\nconst participantAddFromCurrentSelection = () => {\n let selectionType = ELEMENT_SELECTOR.participantSelectionType();\n let selection = ELEMENT_SELECTOR.participantSelection();\n const pList = getParticipantList();\n // Lookup to see if it has been added already.\n for (var i = 0; i < pList.length; i++) {\n if (pList[i].selectiontype === selectionType.value &&\n pList[i].selectionid === selection.value) {\n return;\n }\n }\n pList.push({\n \"selectiontype\": selectionType.value,\n \"selectionid\": selection.value,\n \"role\": \"viewer\"\n });\n // Add it to the form.\n participantAddToForm(selectionType.value, selection.value, 'viewer', true).then();\n // Update in the form.\n participantListUpdate(pList);\n};\n\n/**\n * Update selectable options when changing types\n *\n * @param {HTMLNode} currentTypeSelect\n */\nconst updateSelectionFromType = (currentTypeSelect) => {\n const createNewOption = (selectItem, label, value) => {\n const option = document.createElement('option');\n option.text = label;\n option.value = value;\n\n selectItem.add(option);\n };\n\n const participantData = JSON.parse(ELEMENT_SELECTOR.participantData().dataset.participantData);\n // Clear all selection items.\n const participantSelect = ELEMENT_SELECTOR.participantSelection();\n while (participantSelect.firstChild) {\n participantSelect.removeChild(participantSelect.firstChild);\n }\n // Add options depending on the selection.\n if (currentTypeSelect.selectedIndex !== -1) {\n const options = Object.values(participantData[currentTypeSelect.value].children);\n options.forEach(option => {\n createNewOption(participantSelect, option.name, option.id);\n });\n\n if (currentTypeSelect.value === 'all') {\n createNewOption(participantSelect, '---------------', 'all');\n participantSelect.disabled = true;\n } else {\n participantSelect.disabled = false;\n }\n }\n};\n"],"file":"modform.min.js"} \ No newline at end of file diff --git a/mod/bigbluebuttonbn/amd/src/modform.js b/mod/bigbluebuttonbn/amd/src/modform.js index 7fd0c0393e9..69874aa9178 100644 --- a/mod/bigbluebuttonbn/amd/src/modform.js +++ b/mod/bigbluebuttonbn/amd/src/modform.js @@ -296,8 +296,7 @@ const participantListRoleUpdate = (type, id) => { const pList = getParticipantList(); for (var i = 0; i < pList.length; i++) { - if (pList[i].selectiontype === type && - pList[i].selectionid === (id === '' ? null : parseInt(id))) { + if (pList[i].selectiontype === type && pList[i].selectionid === id) { pList[i].role = participantListRoleSelection.value; } } diff --git a/mod/bigbluebuttonbn/mod_form.php b/mod/bigbluebuttonbn/mod_form.php index 86445265444..5a4e01766a8 100644 --- a/mod/bigbluebuttonbn/mod_form.php +++ b/mod/bigbluebuttonbn/mod_form.php @@ -58,16 +58,13 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { \mod_bigbluebuttonbn\local\config::get('server_url') ); } - $bigbluebuttonbn = null; - if ($this->current->id) { - $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', ['id' => $this->current->id], '*', MUST_EXIST); - } // UI configuration options. $cfg = \mod_bigbluebuttonbn\local\config::get_options(); // Get only those that are allowed. $course = $this->_course; $context = context_course::instance($course->id); + $bigbluebuttonbn = empty($this->get_current()->id) ? null : $this->get_current(); $instancetyperofiles = $this->get_instance_type_profiles(); $this->bigbluebuttonbn_mform_add_block_profiles($mform, $instancetyperofiles); diff --git a/mod/bigbluebuttonbn/templates/participant_form_add.mustache b/mod/bigbluebuttonbn/templates/participant_form_add.mustache index 4c408d892ad..ff0a9389472 100644 --- a/mod/bigbluebuttonbn/templates/participant_form_add.mustache +++ b/mod/bigbluebuttonbn/templates/participant_form_add.mustache @@ -29,6 +29,7 @@ "canRemove": true } }} + {{participanttype}} @@ -40,7 +41,7 @@ {{#str}}mod_form_field_participant_list_text_as, mod_bigbluebuttonbn{{/str}} - {{#roles}} {{/roles}} diff --git a/mod/bigbluebuttonbn/tests/behat/roles.feature b/mod/bigbluebuttonbn/tests/behat/roles.feature new file mode 100644 index 00000000000..4e37f147e40 --- /dev/null +++ b/mod/bigbluebuttonbn/tests/behat/roles.feature @@ -0,0 +1,27 @@ +@mod @mod_bigbluebuttonbn @javascript +Feature: Bigbluebuttonbn rooms + When a meeting is created, roles for each type of participant can be changed + + Background: Make sure that a course is created + And the following course exists: + | name | Test course | + | shortname | C1 | + And the following "users" exist: + | username | firstname | lastname | email | + | traverst | Terry | Travers | t.travers@example.com | + And the following "course enrolments" exist: + | user | course | role | + | traverst | C1 | student | + And the following "activities" exist: + | activity | name | intro | course | idnumber | type | recordings_imported | + | bigbluebuttonbn | RoomRecordings | Test Room Recording description | C1 | bigbluebuttonbn1 | 0 | 0 | + + Scenario: Add a mod_bigbluebuttonbn instance and set the teacher role as moderator + When I am on the "RoomRecordings" "bigbluebuttonbn activity editing" page logged in as "admin" + Then I set the field "bigbluebuttonbn_participant_selection_type" to "Role" + Then I set the field "bigbluebuttonbn_participant_selection" to "Manager" + Then I click on "bigbluebuttonbn_participant_selection_add" "button" + Then I set the field "select-for-role-1" to "Moderator" + Then I press "Save and display" + Then I am on the "RoomRecordings" "bigbluebuttonbn activity editing" page logged in as "admin" + And "[name=select-for-role-1] option[value=moderator][selected]" "css_element" should exist