diff --git a/course/format/amd/build/local/courseeditor/mutations.min.js b/course/format/amd/build/local/courseeditor/mutations.min.js index dbce4c711fa..f84fe804903 100644 --- a/course/format/amd/build/local/courseeditor/mutations.min.js +++ b/course/format/amd/build/local/courseeditor/mutations.min.js @@ -6,6 +6,6 @@ define("core_courseformat/local/courseeditor/mutations",["exports","core/ajax"," * @class core_courseformat/local/courseeditor/mutations * @copyright 2021 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */return _exports.default=class{async _callEditWebservice(action,courseId,ids,targetSectionId,targetCmId){const args={action:action,courseid:courseId,ids:ids};targetSectionId&&(args.targetsectionid=targetSectionId),targetCmId&&(args.targetcmid=targetCmId);let ajaxresult=await _ajax.default.call([{methodname:"core_courseformat_update_course",args:args}])[0];return JSON.parse(ajaxresult)}async _callAddModuleWebservice(courseId,modName,targetSectionNum,targetCmId){const args={courseid:courseId,modname:modName,targetsectionnum:targetSectionNum};targetCmId&&(args.targetcmid=targetCmId);let ajaxresult=await _ajax.default.call([{methodname:"core_courseformat_create_module",args:args}])[0];return JSON.parse(ajaxresult)}async _callNewModuleWebservice(courseId,modName,targetSectionId,targetCmId){const args={courseid:courseId,modname:modName,targetsectionid:targetSectionId};targetCmId&&(args.targetcmid=targetCmId);let ajaxresult=await _ajax.default.call([{methodname:"core_courseformat_new_module",args:args}])[0];return JSON.parse(ajaxresult)}async _sectionBasicAction(stateManager,action,sectionIds,targetSectionId,targetCmId){const logEntry=this._getLoggerEntry(stateManager,action,sectionIds,{targetSectionId:targetSectionId,targetCmId:targetCmId,itemType:"section"}),course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice(action,course.id,sectionIds,targetSectionId,targetCmId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1),stateManager.addLoggerEntry(await logEntry)}async _cmBasicAction(stateManager,action,cmIds,targetSectionId,targetCmId){const logEntry=this._getLoggerEntry(stateManager,action,cmIds,{targetSectionId:targetSectionId,targetCmId:targetCmId,itemType:"cm"}),course=stateManager.get("course");this.cmLock(stateManager,cmIds,!0);const updates=await this._callEditWebservice(action,course.id,cmIds,targetSectionId,targetCmId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.cmLock(stateManager,cmIds,!1),stateManager.addLoggerEntry(await logEntry)}async _getLoggerEntry(stateManager,action,itemIds){var _data$itemType,_data$component;let data=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};isLoggerSet||(stateManager.setLogger(new _srlogger.default),isLoggerSet=!0);const feedbackParams={action:action,itemType:null!==(_data$itemType=data.itemType)&&void 0!==_data$itemType?_data$itemType:action.split("_")[0]};let batch="";if(itemIds.length>1)feedbackParams.count=itemIds.length,batch="_batch";else if(1===itemIds.length){var _itemInfo$title;const itemInfo=stateManager.get(feedbackParams.itemType,itemIds[0]);feedbackParams.name=null!==(_itemInfo$title=itemInfo.title)&&void 0!==_itemInfo$title?_itemInfo$title:itemInfo.name}data.targetSectionId&&(feedbackParams.targetSectionName=stateManager.get("section",data.targetSectionId).title),data.targetCmId&&(feedbackParams.targetCmName=stateManager.get("cm",data.targetCmId).name);return{feedbackMessage:await(0,_str.getString)("".concat(action.toLowerCase(),"_feedback").concat(batch),null!==(_data$component=data.component)&&void 0!==_data$component?_data$component:"core_courseformat",feedbackParams)}}init(stateManager){stateManager.addUpdateTypes({prepareFields:this._prepareFields}),stateManager.setLogger(new _srlogger.default),isLoggerSet=!0}_prepareFields(stateManager,updateName,fields){return fields.locked=!1,fields}async sectionHide(stateManager,sectionIds){await this._sectionBasicAction(stateManager,"section_hide",sectionIds)}async sectionShow(stateManager,sectionIds){await this._sectionBasicAction(stateManager,"section_show",sectionIds)}async cmShow(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_show",cmIds)}async cmHide(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_hide",cmIds)}async cmStealth(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_stealth",cmIds)}async cmDuplicate(stateManager,cmIds,targetSectionId,targetCmId){const logEntry=this._getLoggerEntry(stateManager,"cm_duplicate",cmIds),course=stateManager.get("course"),sectionIds=new Set;targetSectionId?sectionIds.add(targetSectionId):cmIds.forEach((cmId=>{const cm=stateManager.get("cm",cmId);sectionIds.add(cm.sectionid)})),this.sectionLock(stateManager,Array.from(sectionIds),!0);const updates=await this._callEditWebservice("cm_duplicate",course.id,cmIds,targetSectionId,targetCmId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.sectionLock(stateManager,Array.from(sectionIds),!1),stateManager.addLoggerEntry(await logEntry)}async cmMove(stateManager,cmids,targetSectionId,targetCmId){if(!targetSectionId&&!targetCmId)throw new Error("Mutation cmMove requires targetSectionId or targetCmId");const course=stateManager.get("course");this.cmLock(stateManager,cmids,!0);const updates=await this._callEditWebservice("cm_move",course.id,cmids,targetSectionId,targetCmId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.cmLock(stateManager,cmids,!1)}async sectionMove(stateManager,sectionIds,targetSectionId){if(_log.default.debug("sectionMove() is deprecated. Use sectionMoveAfter() instead"),!targetSectionId)throw new Error("Mutation sectionMove requires targetSectionId");const course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice("section_move",course.id,sectionIds,targetSectionId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1)}async sectionMoveAfter(stateManager,sectionIds,targetSectionId){if(!targetSectionId)throw new Error("Mutation sectionMoveAfter requires targetSectionId");const course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice("section_move_after",course.id,sectionIds,targetSectionId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1)}async addSection(stateManager,targetSectionId){targetSectionId||(targetSectionId=0);const course=stateManager.get("course"),updates=await this._callEditWebservice("section_add",course.id,[],targetSectionId);stateManager.processUpdates(updates)}async sectionDelete(stateManager,sectionIds){const course=stateManager.get("course"),updates=await this._callEditWebservice("section_delete",course.id,sectionIds);this.bulkReset(stateManager),stateManager.processUpdates(updates)}async cmDelete(stateManager,cmIds){const course=stateManager.get("course");this.cmLock(stateManager,cmIds,!0);const updates=await this._callEditWebservice("cm_delete",course.id,cmIds);this.bulkReset(stateManager),this.cmLock(stateManager,cmIds,!1),stateManager.processUpdates(updates)}async addModule(stateManager,modName,targetSectionNum,targetCmId){if(!modName)throw new Error("Mutation addModule requires moduleName");if(!targetSectionNum)throw new Error("Mutation addModule requires targetSectionNum");targetCmId||(targetCmId=0);const course=stateManager.get("course"),updates=await this._callAddModuleWebservice(course.id,modName,targetSectionNum,targetCmId);stateManager.processUpdates(updates)}async newModule(stateManager,modName,targetSectionId,targetCmId){if(!modName)throw new Error("Mutation newModule requires moduleName");if(!targetSectionId)throw new Error("Mutation newModule requires targetSectionId");targetCmId||(targetCmId=0);const course=stateManager.get("course"),updates=await this._callNewModuleWebservice(course.id,modName,targetSectionId,targetCmId);stateManager.processUpdates(updates)}cmDrag(stateManager,cmIds,dragValue){this.setPageItem(stateManager),this._setElementsValue(stateManager,"cm",cmIds,"dragging",dragValue)}sectionDrag(stateManager,sectionIds,dragValue){this.setPageItem(stateManager),this._setElementsValue(stateManager,"section",sectionIds,"dragging",dragValue)}cmCompletion(stateManager,cmIds,complete){const newState=complete?1:0;stateManager.setReadOnly(!1),cmIds.forEach((id=>{const element=stateManager.get("cm",id);element&&(element.isoverallcomplete=complete,element.completionstate=newState)})),stateManager.setReadOnly(!0)}async cmMoveRight(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_moveright",cmIds)}async cmMoveLeft(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_moveleft",cmIds)}async cmNoGroups(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_nogroups",cmIds)}async cmVisibleGroups(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_visiblegroups",cmIds)}async cmSeparateGroups(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_separategroups",cmIds)}cmLock(stateManager,cmIds,lockValue){this._setElementsValue(stateManager,"cm",cmIds,"locked",lockValue)}sectionLock(stateManager,sectionIds,lockValue){this._setElementsValue(stateManager,"section",sectionIds,"locked",lockValue)}_setElementsValue(stateManager,name,ids,fieldName,newValue){stateManager.setReadOnly(!1),ids.forEach((id=>{const element=stateManager.get(name,id);element&&(element[fieldName]=newValue)})),stateManager.setReadOnly(!0)}setPageItem(stateManager,type,id,isStatic){let newPageItem;if(void 0!==type&&(newPageItem=stateManager.get(type,id),!newPageItem))return;stateManager.setReadOnly(!1);const course=stateManager.get("course");course.pageItem=null,newPageItem&&(course.pageItem={id:id,type:type,sectionId:"section"==type?newPageItem.id:newPageItem.sectionid,isStatic:isStatic}),stateManager.setReadOnly(!0)}unlockAll(stateManager){const state=stateManager.state;stateManager.setReadOnly(!1),state.section.forEach((section=>{section.locked=!1})),state.cm.forEach((cm=>{cm.locked=!1})),stateManager.setReadOnly(!0)}async sectionIndexCollapsed(stateManager,sectionIds,collapsed){const affectedSections=this._updateStateSectionPreference(stateManager,"indexcollapsed",sectionIds,collapsed);if(!affectedSections)return;const course=stateManager.get("course");let actionName="section_index_collapsed";collapsed||(actionName="section_index_expanded"),await this._callEditWebservice(actionName,course.id,affectedSections)}async allSectionsIndexCollapsed(stateManager,collapsed){const sectionIds=stateManager.getIds("section");this.sectionIndexCollapsed(stateManager,sectionIds,collapsed)}async sectionContentCollapsed(stateManager,sectionIds,collapsed){const affectedSections=this._updateStateSectionPreference(stateManager,"contentcollapsed",sectionIds,collapsed);if(!affectedSections)return;const course=stateManager.get("course");let actionName="section_content_collapsed";collapsed||(actionName="section_content_expanded"),await this._callEditWebservice(actionName,course.id,affectedSections)}_updateStateSectionPreference(stateManager,preferenceName,sectionIds,preferenceValue){stateManager.setReadOnly(!1);const affectedSections=[];return sectionIds.forEach((sectionId=>{const section=stateManager.get("section",sectionId);if(void 0===section)return stateManager.setReadOnly(!0),null;const newValue=null!=preferenceValue?preferenceValue:section[preferenceName];section[preferenceName]!=newValue&&(section[preferenceName]=newValue,affectedSections.push(section.id))})),stateManager.setReadOnly(!0),affectedSections}bulkEnable(stateManager,enabled){const state=stateManager.state;stateManager.setReadOnly(!1),state.bulk.enabled=enabled,state.bulk.selectedType="",state.bulk.selection=[],stateManager.setReadOnly(!0)}bulkReset(stateManager){const state=stateManager.state;stateManager.setReadOnly(!1),state.bulk.selectedType="",state.bulk.selection=[],stateManager.setReadOnly(!0)}cmSelect(stateManager,cmIds){this._addIdsToSelection(stateManager,"cm",cmIds)}cmUnselect(stateManager,cmIds){this._removeIdsFromSelection(stateManager,"cm",cmIds)}sectionSelect(stateManager,sectionIds){this._addIdsToSelection(stateManager,"section",sectionIds)}sectionUnselect(stateManager,sectionIds){this._removeIdsFromSelection(stateManager,"section",sectionIds)}_addIdsToSelection(stateManager,typeName,ids){const bulk=stateManager.state.bulk;if(null==bulk||!bulk.enabled)throw new Error("Bulk is not enabled");if(""!==(null==bulk?void 0:bulk.selectedType)&&(null==bulk?void 0:bulk.selectedType)!==typeName)throw new Error("Cannot add ".concat(typeName," to the current selection"));ids=ids.map((value=>value.toString())),stateManager.setReadOnly(!1),bulk.selectedType=typeName;const newSelection=new Set([...bulk.selection,...ids]);bulk.selection=[...newSelection],stateManager.setReadOnly(!0)}_removeIdsFromSelection(stateManager,typeName,ids){const bulk=stateManager.state.bulk;if(null==bulk||!bulk.enabled)throw new Error("Bulk is not enabled");if(""!==(null==bulk?void 0:bulk.selectedType)&&(null==bulk?void 0:bulk.selectedType)!==typeName)throw new Error("Cannot remove ".concat(typeName," from the current selection"));ids=ids.map((value=>value.toString())),stateManager.setReadOnly(!1);const IdsToFilter=new Set(ids);bulk.selection=bulk.selection.filter((current=>!IdsToFilter.has(current))),0===bulk.selection.length&&(bulk.selectedType=""),stateManager.setReadOnly(!0)}async cmState(stateManager,cmids){this.cmLock(stateManager,cmids,!0);const course=stateManager.get("course"),updates=await this._callEditWebservice("cm_state",course.id,cmids);stateManager.processUpdates(updates),this.cmLock(stateManager,cmids,!1)}async sectionState(stateManager,sectionIds){this.sectionLock(stateManager,sectionIds,!0);const course=stateManager.get("course"),updates=await this._callEditWebservice("section_state",course.id,sectionIds);stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1)}async courseState(stateManager){const course=stateManager.get("course"),updates=await this._callEditWebservice("course_state",course.id);stateManager.processUpdates(updates)}},_exports.default})); + */return _exports.default=class{async _callEditWebservice(action,courseId,ids,targetSectionId,targetCmId){const args={action:action,courseid:courseId,ids:ids};targetSectionId&&(args.targetsectionid=targetSectionId),targetCmId&&(args.targetcmid=targetCmId);let ajaxresult=await _ajax.default.call([{methodname:"core_courseformat_update_course",args:args}])[0];return JSON.parse(ajaxresult)}async _callAddModuleWebservice(courseId,modName,targetSectionNum,targetCmId){const args={courseid:courseId,modname:modName,targetsectionnum:targetSectionNum};targetCmId&&(args.targetcmid=targetCmId);let ajaxresult=await _ajax.default.call([{methodname:"core_courseformat_create_module",args:args}])[0];return JSON.parse(ajaxresult)}async _callNewModuleWebservice(courseId,modName,targetSectionId,targetCmId){const args={courseid:courseId,modname:modName,targetsectionid:targetSectionId};targetCmId&&(args.targetcmid=targetCmId);let ajaxresult=await _ajax.default.call([{methodname:"core_courseformat_new_module",args:args}])[0];return JSON.parse(ajaxresult)}async _sectionBasicAction(stateManager,action,sectionIds,targetSectionId,targetCmId){const logEntry=this._getLoggerEntry(stateManager,action,sectionIds,{targetSectionId:targetSectionId,targetCmId:targetCmId,itemType:"section"}),course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice(action,course.id,sectionIds,targetSectionId,targetCmId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1),stateManager.addLoggerEntry(await logEntry)}async _cmBasicAction(stateManager,action,cmIds,targetSectionId,targetCmId){const logEntry=this._getLoggerEntry(stateManager,action,cmIds,{targetSectionId:targetSectionId,targetCmId:targetCmId,itemType:"cm"}),course=stateManager.get("course");this.cmLock(stateManager,cmIds,!0);const updates=await this._callEditWebservice(action,course.id,cmIds,targetSectionId,targetCmId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.cmLock(stateManager,cmIds,!1),stateManager.addLoggerEntry(await logEntry)}async _getLoggerEntry(stateManager,action,itemIds){var _data$itemType,_data$component;let data=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};isLoggerSet||(stateManager.setLogger(new _srlogger.default),isLoggerSet=!0);const feedbackParams={action:action,itemType:null!==(_data$itemType=data.itemType)&&void 0!==_data$itemType?_data$itemType:action.split("_")[0]};let batch="";if(itemIds.length>1)feedbackParams.count=itemIds.length,batch="_batch";else if(1===itemIds.length){var _itemInfo$title;const itemInfo=stateManager.get(feedbackParams.itemType,itemIds[0]);feedbackParams.name=null!==(_itemInfo$title=itemInfo.title)&&void 0!==_itemInfo$title?_itemInfo$title:itemInfo.name}data.targetSectionId&&(feedbackParams.targetSectionName=stateManager.get("section",data.targetSectionId).title),data.targetCmId&&(feedbackParams.targetCmName=stateManager.get("cm",data.targetCmId).name);return{feedbackMessage:await(0,_str.getString)("".concat(action.toLowerCase(),"_feedback").concat(batch),null!==(_data$component=data.component)&&void 0!==_data$component?_data$component:"core_courseformat",feedbackParams)}}init(stateManager){stateManager.addUpdateTypes({prepareFields:this._prepareFields}),stateManager.setLogger(new _srlogger.default),isLoggerSet=!0}_prepareFields(stateManager,updateName,fields){return fields.locked=!1,fields}async sectionHide(stateManager,sectionIds){await this._sectionBasicAction(stateManager,"section_hide",sectionIds)}async sectionShow(stateManager,sectionIds){await this._sectionBasicAction(stateManager,"section_show",sectionIds)}async cmShow(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_show",cmIds)}async cmHide(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_hide",cmIds)}async cmStealth(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_stealth",cmIds)}async cmDuplicate(stateManager,cmIds,targetSectionId,targetCmId){const logEntry=this._getLoggerEntry(stateManager,"cm_duplicate",cmIds),course=stateManager.get("course"),sectionIds=new Set;targetSectionId?sectionIds.add(targetSectionId):cmIds.forEach((cmId=>{const cm=stateManager.get("cm",cmId);sectionIds.add(cm.sectionid)})),this.sectionLock(stateManager,Array.from(sectionIds),!0);const updates=await this._callEditWebservice("cm_duplicate",course.id,cmIds,targetSectionId,targetCmId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.sectionLock(stateManager,Array.from(sectionIds),!1),stateManager.addLoggerEntry(await logEntry)}async cmMove(stateManager,cmids,targetSectionId,targetCmId){if(!targetSectionId&&!targetCmId)throw new Error("Mutation cmMove requires targetSectionId or targetCmId");const course=stateManager.get("course");this.cmLock(stateManager,cmids,!0);const updates=await this._callEditWebservice("cm_move",course.id,cmids,targetSectionId,targetCmId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.cmLock(stateManager,cmids,!1)}async sectionMove(stateManager,sectionIds,targetSectionId){if(_log.default.debug("sectionMove() is deprecated. Use sectionMoveAfter() instead"),!targetSectionId)throw new Error("Mutation sectionMove requires targetSectionId");const course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice("section_move",course.id,sectionIds,targetSectionId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1)}async sectionMoveAfter(stateManager,sectionIds,targetSectionId){if(!targetSectionId)throw new Error("Mutation sectionMoveAfter requires targetSectionId");const course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice("section_move_after",course.id,sectionIds,targetSectionId);this.bulkReset(stateManager),stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1)}async addSection(stateManager,targetSectionId){targetSectionId||(targetSectionId=0);const course=stateManager.get("course"),updates=await this._callEditWebservice("section_add",course.id,[],targetSectionId);stateManager.processUpdates(updates)}async sectionDelete(stateManager,sectionIds){const course=stateManager.get("course"),updates=await this._callEditWebservice("section_delete",course.id,sectionIds);this.bulkReset(stateManager),stateManager.processUpdates(updates)}async cmDelete(stateManager,cmIds){const course=stateManager.get("course");this.cmLock(stateManager,cmIds,!0);const updates=await this._callEditWebservice("cm_delete",course.id,cmIds);this.bulkReset(stateManager),this.cmLock(stateManager,cmIds,!1),stateManager.processUpdates(updates)}async addModule(stateManager,modName,targetSectionNum,targetCmId){if(!modName)throw new Error("Mutation addModule requires moduleName");if(!targetSectionNum)throw new Error("Mutation addModule requires targetSectionNum");targetCmId||(targetCmId=0);const course=stateManager.get("course"),updates=await this._callAddModuleWebservice(course.id,modName,targetSectionNum,targetCmId);stateManager.processUpdates(updates)}async newModule(stateManager,modName,targetSectionId,targetCmId){if(!modName)throw new Error("Mutation newModule requires moduleName");if(!targetSectionId)throw new Error("Mutation newModule requires targetSectionId");targetCmId||(targetCmId=0);const course=stateManager.get("course"),updates=await this._callNewModuleWebservice(course.id,modName,targetSectionId,targetCmId);stateManager.processUpdates(updates)}cmDrag(stateManager,cmIds,dragValue){this.setPageItem(stateManager),this._setElementsValue(stateManager,"cm",cmIds,"dragging",dragValue)}sectionDrag(stateManager,sectionIds,dragValue){this.setPageItem(stateManager),this._setElementsValue(stateManager,"section",sectionIds,"dragging",dragValue)}async cmCompletion(stateManager,cmIds,complete){const newState=complete?1:0,action=1==newState?"cm_complete":"cm_uncomplete",logEntry=this._getLoggerEntry(stateManager,action,cmIds);stateManager.setReadOnly(!1),cmIds.forEach((id=>{const element=stateManager.get("cm",id);element&&(element.isoverallcomplete=complete,element.completionstate=newState)})),stateManager.setReadOnly(!0),stateManager.addLoggerEntry(await logEntry)}async cmMoveRight(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_moveright",cmIds)}async cmMoveLeft(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_moveleft",cmIds)}async cmNoGroups(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_nogroups",cmIds)}async cmVisibleGroups(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_visiblegroups",cmIds)}async cmSeparateGroups(stateManager,cmIds){await this._cmBasicAction(stateManager,"cm_separategroups",cmIds)}cmLock(stateManager,cmIds,lockValue){this._setElementsValue(stateManager,"cm",cmIds,"locked",lockValue)}sectionLock(stateManager,sectionIds,lockValue){this._setElementsValue(stateManager,"section",sectionIds,"locked",lockValue)}_setElementsValue(stateManager,name,ids,fieldName,newValue){stateManager.setReadOnly(!1),ids.forEach((id=>{const element=stateManager.get(name,id);element&&(element[fieldName]=newValue)})),stateManager.setReadOnly(!0)}setPageItem(stateManager,type,id,isStatic){let newPageItem;if(void 0!==type&&(newPageItem=stateManager.get(type,id),!newPageItem))return;stateManager.setReadOnly(!1);const course=stateManager.get("course");course.pageItem=null,newPageItem&&(course.pageItem={id:id,type:type,sectionId:"section"==type?newPageItem.id:newPageItem.sectionid,isStatic:isStatic}),stateManager.setReadOnly(!0)}unlockAll(stateManager){const state=stateManager.state;stateManager.setReadOnly(!1),state.section.forEach((section=>{section.locked=!1})),state.cm.forEach((cm=>{cm.locked=!1})),stateManager.setReadOnly(!0)}async sectionIndexCollapsed(stateManager,sectionIds,collapsed){const affectedSections=this._updateStateSectionPreference(stateManager,"indexcollapsed",sectionIds,collapsed);if(!affectedSections)return;const course=stateManager.get("course");let actionName="section_index_collapsed";collapsed||(actionName="section_index_expanded"),await this._callEditWebservice(actionName,course.id,affectedSections)}async allSectionsIndexCollapsed(stateManager,collapsed){const sectionIds=stateManager.getIds("section");this.sectionIndexCollapsed(stateManager,sectionIds,collapsed)}async sectionContentCollapsed(stateManager,sectionIds,collapsed){const affectedSections=this._updateStateSectionPreference(stateManager,"contentcollapsed",sectionIds,collapsed);if(!affectedSections)return;const course=stateManager.get("course");let actionName="section_content_collapsed";collapsed||(actionName="section_content_expanded"),await this._callEditWebservice(actionName,course.id,affectedSections)}_updateStateSectionPreference(stateManager,preferenceName,sectionIds,preferenceValue){stateManager.setReadOnly(!1);const affectedSections=[];return sectionIds.forEach((sectionId=>{const section=stateManager.get("section",sectionId);if(void 0===section)return stateManager.setReadOnly(!0),null;const newValue=null!=preferenceValue?preferenceValue:section[preferenceName];section[preferenceName]!=newValue&&(section[preferenceName]=newValue,affectedSections.push(section.id))})),stateManager.setReadOnly(!0),affectedSections}bulkEnable(stateManager,enabled){const state=stateManager.state;stateManager.setReadOnly(!1),state.bulk.enabled=enabled,state.bulk.selectedType="",state.bulk.selection=[],stateManager.setReadOnly(!0)}bulkReset(stateManager){const state=stateManager.state;stateManager.setReadOnly(!1),state.bulk.selectedType="",state.bulk.selection=[],stateManager.setReadOnly(!0)}cmSelect(stateManager,cmIds){this._addIdsToSelection(stateManager,"cm",cmIds)}cmUnselect(stateManager,cmIds){this._removeIdsFromSelection(stateManager,"cm",cmIds)}sectionSelect(stateManager,sectionIds){this._addIdsToSelection(stateManager,"section",sectionIds)}sectionUnselect(stateManager,sectionIds){this._removeIdsFromSelection(stateManager,"section",sectionIds)}_addIdsToSelection(stateManager,typeName,ids){const bulk=stateManager.state.bulk;if(null==bulk||!bulk.enabled)throw new Error("Bulk is not enabled");if(""!==(null==bulk?void 0:bulk.selectedType)&&(null==bulk?void 0:bulk.selectedType)!==typeName)throw new Error("Cannot add ".concat(typeName," to the current selection"));ids=ids.map((value=>value.toString())),stateManager.setReadOnly(!1),bulk.selectedType=typeName;const newSelection=new Set([...bulk.selection,...ids]);bulk.selection=[...newSelection],stateManager.setReadOnly(!0)}_removeIdsFromSelection(stateManager,typeName,ids){const bulk=stateManager.state.bulk;if(null==bulk||!bulk.enabled)throw new Error("Bulk is not enabled");if(""!==(null==bulk?void 0:bulk.selectedType)&&(null==bulk?void 0:bulk.selectedType)!==typeName)throw new Error("Cannot remove ".concat(typeName," from the current selection"));ids=ids.map((value=>value.toString())),stateManager.setReadOnly(!1);const IdsToFilter=new Set(ids);bulk.selection=bulk.selection.filter((current=>!IdsToFilter.has(current))),0===bulk.selection.length&&(bulk.selectedType=""),stateManager.setReadOnly(!0)}async cmState(stateManager,cmids){this.cmLock(stateManager,cmids,!0);const course=stateManager.get("course"),updates=await this._callEditWebservice("cm_state",course.id,cmids);stateManager.processUpdates(updates),this.cmLock(stateManager,cmids,!1)}async sectionState(stateManager,sectionIds){this.sectionLock(stateManager,sectionIds,!0);const course=stateManager.get("course"),updates=await this._callEditWebservice("section_state",course.id,sectionIds);stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1)}async courseState(stateManager){const course=stateManager.get("course"),updates=await this._callEditWebservice("course_state",course.id);stateManager.processUpdates(updates)}},_exports.default})); //# sourceMappingURL=mutations.min.js.map \ No newline at end of file diff --git a/course/format/amd/build/local/courseeditor/mutations.min.js.map b/course/format/amd/build/local/courseeditor/mutations.min.js.map index ad8a0d0b9c0..1646cd618bf 100644 --- a/course/format/amd/build/local/courseeditor/mutations.min.js.map +++ b/course/format/amd/build/local/courseeditor/mutations.min.js.map @@ -1 +1 @@ -{"version":3,"file":"mutations.min.js","sources":["../../../src/local/courseeditor/mutations.js"],"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\nimport ajax from 'core/ajax';\nimport {getString} from \"core/str\";\nimport log from 'core/log';\nimport SRLogger from \"core/local/reactive/srlogger\";\n\n/**\n * Flag to determine whether the screen reader-only logger has already been set, so we only need to set it once.\n *\n * @type {boolean}\n */\nlet isLoggerSet = false;\n\n/**\n * Default mutation manager\n *\n * @module core_courseformat/local/courseeditor/mutations\n * @class core_courseformat/local/courseeditor/mutations\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nexport default class {\n\n // All course editor mutations for Moodle 4.0 will be located in this file.\n\n /**\n * Private method to call core_courseformat_update_course webservice.\n *\n * @method _callEditWebservice\n * @param {string} action\n * @param {number} courseId\n * @param {array} ids\n * @param {number} targetSectionId optional target section id (for moving actions)\n * @param {number} targetCmId optional target cm id (for moving actions)\n */\n async _callEditWebservice(action, courseId, ids, targetSectionId, targetCmId) {\n const args = {\n action,\n courseid: courseId,\n ids,\n };\n if (targetSectionId) {\n args.targetsectionid = targetSectionId;\n }\n if (targetCmId) {\n args.targetcmid = targetCmId;\n }\n let ajaxresult = await ajax.call([{\n methodname: 'core_courseformat_update_course',\n args,\n }])[0];\n return JSON.parse(ajaxresult);\n }\n\n /**\n * Private method to call core_courseformat_create_module webservice.\n *\n * @method _callEditWebservice\n * @param {number} courseId\n * @param {string} modName module name\n * @param {number} targetSectionNum target section number\n * @param {number} targetCmId optional target cm id\n */\n async _callAddModuleWebservice(courseId, modName, targetSectionNum, targetCmId) {\n const args = {\n courseid: courseId,\n modname: modName,\n targetsectionnum: targetSectionNum,\n };\n if (targetCmId) {\n args.targetcmid = targetCmId;\n }\n let ajaxresult = await ajax.call([{\n methodname: 'core_courseformat_create_module',\n args,\n }])[0];\n return JSON.parse(ajaxresult);\n }\n\n /**\n * Private method to call core_courseformat_new_module webservice.\n *\n * @method _callEditWebservice\n * @param {number} courseId\n * @param {string} modName module name\n * @param {number} targetSectionId target section number\n * @param {number} targetCmId optional target cm id\n */\n async _callNewModuleWebservice(courseId, modName, targetSectionId, targetCmId) {\n const args = {\n courseid: courseId,\n modname: modName,\n targetsectionid: targetSectionId,\n };\n if (targetCmId) {\n args.targetcmid = targetCmId;\n }\n let ajaxresult = await ajax.call([{\n methodname: 'core_courseformat_new_module',\n args,\n }])[0];\n return JSON.parse(ajaxresult);\n }\n\n /**\n * Execute a basic section state action.\n * @param {StateManager} stateManager the current state manager\n * @param {string} action the action name\n * @param {array} sectionIds the section ids\n * @param {number} targetSectionId optional target section id (for moving actions)\n * @param {number} targetCmId optional target cm id (for moving actions)\n */\n async _sectionBasicAction(stateManager, action, sectionIds, targetSectionId, targetCmId) {\n const logEntry = this._getLoggerEntry(stateManager, action, sectionIds, {\n targetSectionId,\n targetCmId,\n itemType: 'section',\n });\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice(\n action,\n course.id,\n sectionIds,\n targetSectionId,\n targetCmId\n );\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n stateManager.addLoggerEntry(await logEntry);\n }\n\n /**\n * Execute a basic course module state action.\n * @param {StateManager} stateManager the current state manager\n * @param {string} action the action name\n * @param {array} cmIds the cm ids\n * @param {number} targetSectionId optional target section id (for moving actions)\n * @param {number} targetCmId optional target cm id (for moving actions)\n */\n async _cmBasicAction(stateManager, action, cmIds, targetSectionId, targetCmId) {\n const logEntry = this._getLoggerEntry(stateManager, action, cmIds, {\n targetSectionId,\n targetCmId,\n itemType: 'cm',\n });\n const course = stateManager.get('course');\n this.cmLock(stateManager, cmIds, true);\n const updates = await this._callEditWebservice(\n action,\n course.id,\n cmIds,\n targetSectionId,\n targetCmId\n );\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.cmLock(stateManager, cmIds, false);\n stateManager.addLoggerEntry(await logEntry);\n }\n\n /**\n * Get log entry for the current action.\n * @param {StateManager} stateManager the current state manager\n * @param {string} action the action name\n * @param {int[]|null} itemIds the element ids\n * @param {Object|undefined} data extra params for the log entry\n * @param {string|undefined} data.itemType the element type (will be taken from action if none)\n * @param {int|null|undefined} data.targetSectionId the target section id\n * @param {int|null|undefined} data.targetCmId the target cm id\n * @param {String|null|undefined} data.component optional component (for format plugins)\n * @return {Object} the log entry\n */\n async _getLoggerEntry(stateManager, action, itemIds, data = {}) {\n if (!isLoggerSet) {\n // In case the logger has not been set from init(), ensure we set the logger.\n stateManager.setLogger(new SRLogger());\n isLoggerSet = true;\n }\n const feedbackParams = {\n action,\n itemType: data.itemType ?? action.split('_')[0],\n };\n let batch = '';\n if (itemIds.length > 1) {\n feedbackParams.count = itemIds.length;\n batch = '_batch';\n } else if (itemIds.length === 1) {\n const itemInfo = stateManager.get(feedbackParams.itemType, itemIds[0]);\n feedbackParams.name = itemInfo.title ?? itemInfo.name;\n // Apply shortener for modules like label.\n }\n if (data.targetSectionId) {\n feedbackParams.targetSectionName = stateManager.get('section', data.targetSectionId).title;\n }\n if (data.targetCmId) {\n feedbackParams.targetCmName = stateManager.get('cm', data.targetCmId).name;\n }\n\n const message = await getString(\n `${action.toLowerCase()}_feedback${batch}`,\n data.component ?? 'core_courseformat',\n feedbackParams\n );\n\n return {\n feedbackMessage: message,\n };\n }\n\n /**\n * Mutation module initialize.\n *\n * The reactive instance will execute this method when addMutations or setMutation is invoked.\n *\n * @param {StateManager} stateManager the state manager\n */\n init(stateManager) {\n // Add a method to prepare the fields when some update is coming from the server.\n stateManager.addUpdateTypes({\n prepareFields: this._prepareFields,\n });\n // Use the screen reader-only logger (SRLogger) to handle the feedback messages from the mutations.\n stateManager.setLogger(new SRLogger());\n isLoggerSet = true;\n }\n\n /**\n * Add default values to state elements.\n *\n * This method is called every time a webservice returns a update state message.\n *\n * @param {Object} stateManager the state manager\n * @param {String} updateName the state element to update\n * @param {Object} fields the new data\n * @returns {Object} final fields data\n */\n _prepareFields(stateManager, updateName, fields) {\n // Any update should unlock the element.\n fields.locked = false;\n return fields;\n }\n\n /**\n * Hides sections.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n */\n async sectionHide(stateManager, sectionIds) {\n await this._sectionBasicAction(stateManager, 'section_hide', sectionIds);\n }\n\n /**\n * Show sections.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n */\n async sectionShow(stateManager, sectionIds) {\n await this._sectionBasicAction(stateManager, 'section_show', sectionIds);\n }\n\n /**\n * Show cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmShow(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_show', cmIds);\n }\n\n /**\n * Hide cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmHide(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_hide', cmIds);\n }\n\n /**\n * Stealth cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmStealth(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_stealth', cmIds);\n }\n\n /**\n * Duplicate course modules\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of course modules ids\n * @param {number|undefined} targetSectionId the optional target sectionId\n * @param {number|undefined} targetCmId the target course module id\n */\n async cmDuplicate(stateManager, cmIds, targetSectionId, targetCmId) {\n const logEntry = this._getLoggerEntry(stateManager, 'cm_duplicate', cmIds);\n const course = stateManager.get('course');\n // Lock all target sections.\n const sectionIds = new Set();\n if (targetSectionId) {\n sectionIds.add(targetSectionId);\n } else {\n cmIds.forEach((cmId) => {\n const cm = stateManager.get('cm', cmId);\n sectionIds.add(cm.sectionid);\n });\n }\n this.sectionLock(stateManager, Array.from(sectionIds), true);\n\n const updates = await this._callEditWebservice('cm_duplicate', course.id, cmIds, targetSectionId, targetCmId);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n\n this.sectionLock(stateManager, Array.from(sectionIds), false);\n stateManager.addLoggerEntry(await logEntry);\n }\n\n /**\n * Move course modules to specific course location.\n *\n * Note that one of targetSectionId or targetCmId should be provided in order to identify the\n * new location:\n * - targetCmId: the activities will be located avobe the target cm. The targetSectionId\n * value will be ignored in this case.\n * - targetSectionId: the activities will be appended to the section. In this case\n * targetSectionId should not be present.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmids the list of cm ids to move\n * @param {number} targetSectionId the target section id\n * @param {number} targetCmId the target course module id\n */\n async cmMove(stateManager, cmids, targetSectionId, targetCmId) {\n if (!targetSectionId && !targetCmId) {\n throw new Error(`Mutation cmMove requires targetSectionId or targetCmId`);\n }\n const course = stateManager.get('course');\n this.cmLock(stateManager, cmids, true);\n const updates = await this._callEditWebservice('cm_move', course.id, cmids, targetSectionId, targetCmId);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.cmLock(stateManager, cmids, false);\n }\n\n /**\n * Move course modules to specific course location.\n *\n * @deprecated since Moodle 4.4 MDL-77038.\n * @todo MDL-80116 This will be deleted in Moodle 4.8.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids to move\n * @param {number} targetSectionId the target section id\n */\n async sectionMove(stateManager, sectionIds, targetSectionId) {\n log.debug('sectionMove() is deprecated. Use sectionMoveAfter() instead');\n if (!targetSectionId) {\n throw new Error(`Mutation sectionMove requires targetSectionId`);\n }\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice('section_move', course.id, sectionIds, targetSectionId);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n }\n\n /**\n * Move course modules after a specific course location.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids to move\n * @param {number} targetSectionId the target section id\n */\n async sectionMoveAfter(stateManager, sectionIds, targetSectionId) {\n if (!targetSectionId) {\n throw new Error(`Mutation sectionMoveAfter requires targetSectionId`);\n }\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice('section_move_after', course.id, sectionIds, targetSectionId);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n }\n\n /**\n * Add a new section to a specific course location.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {number} targetSectionId optional the target section id\n */\n async addSection(stateManager, targetSectionId) {\n if (!targetSectionId) {\n targetSectionId = 0;\n }\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('section_add', course.id, [], targetSectionId);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Delete sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of course modules ids\n */\n async sectionDelete(stateManager, sectionIds) {\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('section_delete', course.id, sectionIds);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Delete cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of section ids\n */\n async cmDelete(stateManager, cmIds) {\n const course = stateManager.get('course');\n this.cmLock(stateManager, cmIds, true);\n const updates = await this._callEditWebservice('cm_delete', course.id, cmIds);\n this.bulkReset(stateManager);\n this.cmLock(stateManager, cmIds, false);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Add a new module to a specific course section.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {string} modName the modulename to add\n * @param {number} targetSectionNum the target section number\n * @param {number} targetCmId optional the target cm id\n */\n async addModule(stateManager, modName, targetSectionNum, targetCmId) {\n if (!modName) {\n throw new Error(`Mutation addModule requires moduleName`);\n }\n if (!targetSectionNum) {\n throw new Error(`Mutation addModule requires targetSectionNum`);\n }\n if (!targetCmId) {\n targetCmId = 0;\n }\n const course = stateManager.get('course');\n const updates = await this._callAddModuleWebservice(course.id, modName, targetSectionNum, targetCmId);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Add a new module to a specific course section.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {string} modName the modulename to add\n * @param {number} targetSectionId the target section id\n * @param {number} targetCmId optional the target cm id\n */\n async newModule(stateManager, modName, targetSectionId, targetCmId) {\n if (!modName) {\n throw new Error(`Mutation newModule requires moduleName`);\n }\n if (!targetSectionId) {\n throw new Error(`Mutation newModule requires targetSectionId`);\n }\n if (!targetCmId) {\n targetCmId = 0;\n }\n const course = stateManager.get('course');\n const updates = await this._callNewModuleWebservice(course.id, modName, targetSectionId, targetCmId);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Mark or unmark course modules as dragging.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of course modules ids\n * @param {bool} dragValue the new dragging value\n */\n cmDrag(stateManager, cmIds, dragValue) {\n this.setPageItem(stateManager);\n this._setElementsValue(stateManager, 'cm', cmIds, 'dragging', dragValue);\n }\n\n /**\n * Mark or unmark course sections as dragging.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n * @param {bool} dragValue the new dragging value\n */\n sectionDrag(stateManager, sectionIds, dragValue) {\n this.setPageItem(stateManager);\n this._setElementsValue(stateManager, 'section', sectionIds, 'dragging', dragValue);\n }\n\n /**\n * Mark or unmark course modules as complete.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of course modules ids\n * @param {bool} complete the new completion value\n */\n cmCompletion(stateManager, cmIds, complete) {\n const newState = (complete) ? 1 : 0;\n stateManager.setReadOnly(false);\n cmIds.forEach((id) => {\n const element = stateManager.get('cm', id);\n if (element) {\n element.isoverallcomplete = complete;\n element.completionstate = newState;\n }\n });\n stateManager.setReadOnly(true);\n }\n\n /**\n * Move cms to the right: indent = 1.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmMoveRight(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_moveright', cmIds);\n }\n\n /**\n * Move cms to the left: indent = 0.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmMoveLeft(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_moveleft', cmIds);\n }\n\n /**\n * Set cms group mode to NOGROUPS.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmNoGroups(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_nogroups', cmIds);\n }\n\n /**\n * Set cms group mode to VISIBLEGROUPS.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmVisibleGroups(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_visiblegroups', cmIds);\n }\n\n /**\n * Set cms group mode to SEPARATEGROUPS.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmSeparateGroups(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_separategroups', cmIds);\n }\n\n /**\n * Lock or unlock course modules.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of course modules ids\n * @param {bool} lockValue the new locked value\n */\n cmLock(stateManager, cmIds, lockValue) {\n this._setElementsValue(stateManager, 'cm', cmIds, 'locked', lockValue);\n }\n\n /**\n * Lock or unlock course sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n * @param {bool} lockValue the new locked value\n */\n sectionLock(stateManager, sectionIds, lockValue) {\n this._setElementsValue(stateManager, 'section', sectionIds, 'locked', lockValue);\n }\n\n _setElementsValue(stateManager, name, ids, fieldName, newValue) {\n stateManager.setReadOnly(false);\n ids.forEach((id) => {\n const element = stateManager.get(name, id);\n if (element) {\n element[fieldName] = newValue;\n }\n });\n stateManager.setReadOnly(true);\n }\n\n /**\n * Set the page current item.\n *\n * Only one element of the course state can be the page item at a time.\n *\n * There are several actions that can alter the page current item. For example, when the user is in an activity\n * page, the page item is always the activity one. However, in a course page, when the user scrolls to an element,\n * this element get the page item.\n *\n * If the page item is static means that it is not meant to change. This is important because\n * static page items has some special logic. For example, if a cm is the static page item\n * and it is inside a collapsed section, the course index will expand the section to make it visible.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {String|undefined} type the element type (section or cm). Undefined will remove the current page item.\n * @param {Number|undefined} id the element id\n * @param {boolean|undefined} isStatic if the page item is static\n */\n setPageItem(stateManager, type, id, isStatic) {\n let newPageItem;\n if (type !== undefined) {\n newPageItem = stateManager.get(type, id);\n if (!newPageItem) {\n return;\n }\n }\n stateManager.setReadOnly(false);\n // Remove the current page item.\n const course = stateManager.get('course');\n course.pageItem = null;\n // Save the new page item.\n if (newPageItem) {\n course.pageItem = {\n id,\n type,\n sectionId: (type == 'section') ? newPageItem.id : newPageItem.sectionid,\n isStatic,\n };\n }\n stateManager.setReadOnly(true);\n }\n\n /**\n * Unlock all course elements.\n *\n * @param {StateManager} stateManager the current state manager\n */\n unlockAll(stateManager) {\n const state = stateManager.state;\n stateManager.setReadOnly(false);\n state.section.forEach((section) => {\n section.locked = false;\n });\n state.cm.forEach((cm) => {\n cm.locked = false;\n });\n stateManager.setReadOnly(true);\n }\n\n /**\n * Update the course index collapsed attribute of some sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the affected section ids\n * @param {boolean} collapsed the new collapsed value\n */\n async sectionIndexCollapsed(stateManager, sectionIds, collapsed) {\n const affectedSections = this._updateStateSectionPreference(stateManager, 'indexcollapsed', sectionIds, collapsed);\n if (!affectedSections) {\n return;\n }\n const course = stateManager.get('course');\n let actionName = 'section_index_collapsed';\n if (!collapsed) {\n actionName = 'section_index_expanded';\n }\n await this._callEditWebservice(actionName, course.id, affectedSections);\n }\n\n /**\n * Update the course index collapsed attribute of all sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {boolean} collapsed the new collapsed value\n */\n async allSectionsIndexCollapsed(stateManager, collapsed) {\n const sectionIds = stateManager.getIds('section');\n this.sectionIndexCollapsed(stateManager, sectionIds, collapsed);\n }\n\n /**\n * Update the course content collapsed attribute of some sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the affected section ids\n * @param {boolean} collapsed the new collapsed value\n */\n async sectionContentCollapsed(stateManager, sectionIds, collapsed) {\n const affectedSections = this._updateStateSectionPreference(stateManager, 'contentcollapsed', sectionIds, collapsed);\n if (!affectedSections) {\n return;\n }\n const course = stateManager.get('course');\n let actionName = 'section_content_collapsed';\n if (!collapsed) {\n actionName = 'section_content_expanded';\n }\n await this._callEditWebservice(actionName, course.id, affectedSections);\n }\n\n /**\n * Private batch update for a section preference attribute.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {string} preferenceName the preference name\n * @param {array} sectionIds the affected section ids\n * @param {boolean} preferenceValue the new preferenceValue value\n * @return {Number[]|null} sections ids with the preference value true or null if no update is required\n */\n _updateStateSectionPreference(stateManager, preferenceName, sectionIds, preferenceValue) {\n stateManager.setReadOnly(false);\n const affectedSections = [];\n // Check if we need to update preferences.\n sectionIds.forEach(sectionId => {\n const section = stateManager.get('section', sectionId);\n if (section === undefined) {\n stateManager.setReadOnly(true);\n return null;\n }\n const newValue = preferenceValue ?? section[preferenceName];\n if (section[preferenceName] != newValue) {\n section[preferenceName] = newValue;\n affectedSections.push(section.id);\n }\n });\n stateManager.setReadOnly(true);\n return affectedSections;\n }\n\n /**\n * Enable/disable bulk editing.\n *\n * Note: reenabling the bulk will clean the current selection.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {Boolean} enabled the new bulk state.\n */\n bulkEnable(stateManager, enabled) {\n const state = stateManager.state;\n stateManager.setReadOnly(false);\n state.bulk.enabled = enabled;\n state.bulk.selectedType = '';\n state.bulk.selection = [];\n stateManager.setReadOnly(true);\n }\n\n /**\n * Reset the current selection.\n * @param {StateManager} stateManager the current state manager\n */\n bulkReset(stateManager) {\n const state = stateManager.state;\n stateManager.setReadOnly(false);\n state.bulk.selectedType = '';\n state.bulk.selection = [];\n stateManager.setReadOnly(true);\n }\n\n /**\n * Select a list of cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n cmSelect(stateManager, cmIds) {\n this._addIdsToSelection(stateManager, 'cm', cmIds);\n }\n\n /**\n * Unselect a list of cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n cmUnselect(stateManager, cmIds) {\n this._removeIdsFromSelection(stateManager, 'cm', cmIds);\n }\n\n /**\n * Select a list of sections.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of cm ids\n */\n sectionSelect(stateManager, sectionIds) {\n this._addIdsToSelection(stateManager, 'section', sectionIds);\n }\n\n /**\n * Unselect a list of sections.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of cm ids\n */\n sectionUnselect(stateManager, sectionIds) {\n this._removeIdsFromSelection(stateManager, 'section', sectionIds);\n }\n\n /**\n * Add some ids to the current bulk selection.\n * @param {StateManager} stateManager the current state manager\n * @param {String} typeName the type name (section/cm)\n * @param {array} ids the list of ids\n */\n _addIdsToSelection(stateManager, typeName, ids) {\n const bulk = stateManager.state.bulk;\n if (!bulk?.enabled) {\n throw new Error(`Bulk is not enabled`);\n }\n if (bulk?.selectedType !== \"\" && bulk?.selectedType !== typeName) {\n throw new Error(`Cannot add ${typeName} to the current selection`);\n }\n\n // Stored ids are strings for compatability with HTML data attributes.\n ids = ids.map(value => value.toString());\n\n stateManager.setReadOnly(false);\n bulk.selectedType = typeName;\n const newSelection = new Set([...bulk.selection, ...ids]);\n bulk.selection = [...newSelection];\n stateManager.setReadOnly(true);\n }\n\n /**\n * Remove some ids to the current bulk selection.\n *\n * The method resets the selection type if the current selection is empty.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {String} typeName the type name (section/cm)\n * @param {array} ids the list of ids\n */\n _removeIdsFromSelection(stateManager, typeName, ids) {\n const bulk = stateManager.state.bulk;\n if (!bulk?.enabled) {\n throw new Error(`Bulk is not enabled`);\n }\n if (bulk?.selectedType !== \"\" && bulk?.selectedType !== typeName) {\n throw new Error(`Cannot remove ${typeName} from the current selection`);\n }\n\n // Stored ids are strings for compatability with HTML data attributes.\n ids = ids.map(value => value.toString());\n\n stateManager.setReadOnly(false);\n const IdsToFilter = new Set(ids);\n bulk.selection = bulk.selection.filter(current => !IdsToFilter.has(current));\n if (bulk.selection.length === 0) {\n bulk.selectedType = '';\n }\n stateManager.setReadOnly(true);\n }\n\n /**\n * Get updated state data related to some cm ids.\n *\n * @method cmState\n * @param {StateManager} stateManager the current state\n * @param {array} cmids the list of cm ids to update\n */\n async cmState(stateManager, cmids) {\n this.cmLock(stateManager, cmids, true);\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('cm_state', course.id, cmids);\n stateManager.processUpdates(updates);\n this.cmLock(stateManager, cmids, false);\n }\n\n /**\n * Get updated state data related to some section ids.\n *\n * @method sectionState\n * @param {StateManager} stateManager the current state\n * @param {array} sectionIds the list of section ids to update\n */\n async sectionState(stateManager, sectionIds) {\n this.sectionLock(stateManager, sectionIds, true);\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('section_state', course.id, sectionIds);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n }\n\n /**\n * Get the full updated state data of the course.\n *\n * @param {StateManager} stateManager the current state\n */\n async courseState(stateManager) {\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('course_state', course.id);\n stateManager.processUpdates(updates);\n }\n\n}\n"],"names":["isLoggerSet","action","courseId","ids","targetSectionId","targetCmId","args","courseid","targetsectionid","targetcmid","ajaxresult","ajax","call","methodname","JSON","parse","modName","targetSectionNum","modname","targetsectionnum","stateManager","sectionIds","logEntry","this","_getLoggerEntry","itemType","course","get","sectionLock","updates","_callEditWebservice","id","bulkReset","processUpdates","addLoggerEntry","cmIds","cmLock","itemIds","data","setLogger","SRLogger","feedbackParams","split","batch","length","count","itemInfo","name","title","targetSectionName","targetCmName","feedbackMessage","toLowerCase","component","init","addUpdateTypes","prepareFields","_prepareFields","updateName","fields","locked","_sectionBasicAction","_cmBasicAction","Set","add","forEach","cmId","cm","sectionid","Array","from","cmids","Error","debug","_callAddModuleWebservice","_callNewModuleWebservice","cmDrag","dragValue","setPageItem","_setElementsValue","sectionDrag","cmCompletion","complete","newState","setReadOnly","element","isoverallcomplete","completionstate","lockValue","fieldName","newValue","type","isStatic","newPageItem","undefined","pageItem","sectionId","unlockAll","state","section","collapsed","affectedSections","_updateStateSectionPreference","actionName","getIds","sectionIndexCollapsed","preferenceName","preferenceValue","push","bulkEnable","enabled","bulk","selectedType","selection","cmSelect","_addIdsToSelection","cmUnselect","_removeIdsFromSelection","sectionSelect","sectionUnselect","typeName","map","value","toString","newSelection","IdsToFilter","filter","current","has"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"mutations.min.js","sources":["../../../src/local/courseeditor/mutations.js"],"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\nimport ajax from 'core/ajax';\nimport {getString} from \"core/str\";\nimport log from 'core/log';\nimport SRLogger from \"core/local/reactive/srlogger\";\n\n/**\n * Flag to determine whether the screen reader-only logger has already been set, so we only need to set it once.\n *\n * @type {boolean}\n */\nlet isLoggerSet = false;\n\n/**\n * Default mutation manager\n *\n * @module core_courseformat/local/courseeditor/mutations\n * @class core_courseformat/local/courseeditor/mutations\n * @copyright 2021 Ferran Recio \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nexport default class {\n\n // All course editor mutations for Moodle 4.0 will be located in this file.\n\n /**\n * Private method to call core_courseformat_update_course webservice.\n *\n * @method _callEditWebservice\n * @param {string} action\n * @param {number} courseId\n * @param {array} ids\n * @param {number} targetSectionId optional target section id (for moving actions)\n * @param {number} targetCmId optional target cm id (for moving actions)\n */\n async _callEditWebservice(action, courseId, ids, targetSectionId, targetCmId) {\n const args = {\n action,\n courseid: courseId,\n ids,\n };\n if (targetSectionId) {\n args.targetsectionid = targetSectionId;\n }\n if (targetCmId) {\n args.targetcmid = targetCmId;\n }\n let ajaxresult = await ajax.call([{\n methodname: 'core_courseformat_update_course',\n args,\n }])[0];\n return JSON.parse(ajaxresult);\n }\n\n /**\n * Private method to call core_courseformat_create_module webservice.\n *\n * @method _callEditWebservice\n * @param {number} courseId\n * @param {string} modName module name\n * @param {number} targetSectionNum target section number\n * @param {number} targetCmId optional target cm id\n */\n async _callAddModuleWebservice(courseId, modName, targetSectionNum, targetCmId) {\n const args = {\n courseid: courseId,\n modname: modName,\n targetsectionnum: targetSectionNum,\n };\n if (targetCmId) {\n args.targetcmid = targetCmId;\n }\n let ajaxresult = await ajax.call([{\n methodname: 'core_courseformat_create_module',\n args,\n }])[0];\n return JSON.parse(ajaxresult);\n }\n\n /**\n * Private method to call core_courseformat_new_module webservice.\n *\n * @method _callEditWebservice\n * @param {number} courseId\n * @param {string} modName module name\n * @param {number} targetSectionId target section number\n * @param {number} targetCmId optional target cm id\n */\n async _callNewModuleWebservice(courseId, modName, targetSectionId, targetCmId) {\n const args = {\n courseid: courseId,\n modname: modName,\n targetsectionid: targetSectionId,\n };\n if (targetCmId) {\n args.targetcmid = targetCmId;\n }\n let ajaxresult = await ajax.call([{\n methodname: 'core_courseformat_new_module',\n args,\n }])[0];\n return JSON.parse(ajaxresult);\n }\n\n /**\n * Execute a basic section state action.\n * @param {StateManager} stateManager the current state manager\n * @param {string} action the action name\n * @param {array} sectionIds the section ids\n * @param {number} targetSectionId optional target section id (for moving actions)\n * @param {number} targetCmId optional target cm id (for moving actions)\n */\n async _sectionBasicAction(stateManager, action, sectionIds, targetSectionId, targetCmId) {\n const logEntry = this._getLoggerEntry(stateManager, action, sectionIds, {\n targetSectionId,\n targetCmId,\n itemType: 'section',\n });\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice(\n action,\n course.id,\n sectionIds,\n targetSectionId,\n targetCmId\n );\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n stateManager.addLoggerEntry(await logEntry);\n }\n\n /**\n * Execute a basic course module state action.\n * @param {StateManager} stateManager the current state manager\n * @param {string} action the action name\n * @param {array} cmIds the cm ids\n * @param {number} targetSectionId optional target section id (for moving actions)\n * @param {number} targetCmId optional target cm id (for moving actions)\n */\n async _cmBasicAction(stateManager, action, cmIds, targetSectionId, targetCmId) {\n const logEntry = this._getLoggerEntry(stateManager, action, cmIds, {\n targetSectionId,\n targetCmId,\n itemType: 'cm',\n });\n const course = stateManager.get('course');\n this.cmLock(stateManager, cmIds, true);\n const updates = await this._callEditWebservice(\n action,\n course.id,\n cmIds,\n targetSectionId,\n targetCmId\n );\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.cmLock(stateManager, cmIds, false);\n stateManager.addLoggerEntry(await logEntry);\n }\n\n /**\n * Get log entry for the current action.\n * @param {StateManager} stateManager the current state manager\n * @param {string} action the action name\n * @param {int[]|null} itemIds the element ids\n * @param {Object|undefined} data extra params for the log entry\n * @param {string|undefined} data.itemType the element type (will be taken from action if none)\n * @param {int|null|undefined} data.targetSectionId the target section id\n * @param {int|null|undefined} data.targetCmId the target cm id\n * @param {String|null|undefined} data.component optional component (for format plugins)\n * @return {Object} the log entry\n */\n async _getLoggerEntry(stateManager, action, itemIds, data = {}) {\n if (!isLoggerSet) {\n // In case the logger has not been set from init(), ensure we set the logger.\n stateManager.setLogger(new SRLogger());\n isLoggerSet = true;\n }\n const feedbackParams = {\n action,\n itemType: data.itemType ?? action.split('_')[0],\n };\n let batch = '';\n if (itemIds.length > 1) {\n feedbackParams.count = itemIds.length;\n batch = '_batch';\n } else if (itemIds.length === 1) {\n const itemInfo = stateManager.get(feedbackParams.itemType, itemIds[0]);\n feedbackParams.name = itemInfo.title ?? itemInfo.name;\n // Apply shortener for modules like label.\n }\n if (data.targetSectionId) {\n feedbackParams.targetSectionName = stateManager.get('section', data.targetSectionId).title;\n }\n if (data.targetCmId) {\n feedbackParams.targetCmName = stateManager.get('cm', data.targetCmId).name;\n }\n\n const message = await getString(\n `${action.toLowerCase()}_feedback${batch}`,\n data.component ?? 'core_courseformat',\n feedbackParams\n );\n\n return {\n feedbackMessage: message,\n };\n }\n\n /**\n * Mutation module initialize.\n *\n * The reactive instance will execute this method when addMutations or setMutation is invoked.\n *\n * @param {StateManager} stateManager the state manager\n */\n init(stateManager) {\n // Add a method to prepare the fields when some update is coming from the server.\n stateManager.addUpdateTypes({\n prepareFields: this._prepareFields,\n });\n // Use the screen reader-only logger (SRLogger) to handle the feedback messages from the mutations.\n stateManager.setLogger(new SRLogger());\n isLoggerSet = true;\n }\n\n /**\n * Add default values to state elements.\n *\n * This method is called every time a webservice returns a update state message.\n *\n * @param {Object} stateManager the state manager\n * @param {String} updateName the state element to update\n * @param {Object} fields the new data\n * @returns {Object} final fields data\n */\n _prepareFields(stateManager, updateName, fields) {\n // Any update should unlock the element.\n fields.locked = false;\n return fields;\n }\n\n /**\n * Hides sections.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n */\n async sectionHide(stateManager, sectionIds) {\n await this._sectionBasicAction(stateManager, 'section_hide', sectionIds);\n }\n\n /**\n * Show sections.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n */\n async sectionShow(stateManager, sectionIds) {\n await this._sectionBasicAction(stateManager, 'section_show', sectionIds);\n }\n\n /**\n * Show cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmShow(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_show', cmIds);\n }\n\n /**\n * Hide cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmHide(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_hide', cmIds);\n }\n\n /**\n * Stealth cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmStealth(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_stealth', cmIds);\n }\n\n /**\n * Duplicate course modules\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of course modules ids\n * @param {number|undefined} targetSectionId the optional target sectionId\n * @param {number|undefined} targetCmId the target course module id\n */\n async cmDuplicate(stateManager, cmIds, targetSectionId, targetCmId) {\n const logEntry = this._getLoggerEntry(stateManager, 'cm_duplicate', cmIds);\n const course = stateManager.get('course');\n // Lock all target sections.\n const sectionIds = new Set();\n if (targetSectionId) {\n sectionIds.add(targetSectionId);\n } else {\n cmIds.forEach((cmId) => {\n const cm = stateManager.get('cm', cmId);\n sectionIds.add(cm.sectionid);\n });\n }\n this.sectionLock(stateManager, Array.from(sectionIds), true);\n\n const updates = await this._callEditWebservice('cm_duplicate', course.id, cmIds, targetSectionId, targetCmId);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n\n this.sectionLock(stateManager, Array.from(sectionIds), false);\n stateManager.addLoggerEntry(await logEntry);\n }\n\n /**\n * Move course modules to specific course location.\n *\n * Note that one of targetSectionId or targetCmId should be provided in order to identify the\n * new location:\n * - targetCmId: the activities will be located avobe the target cm. The targetSectionId\n * value will be ignored in this case.\n * - targetSectionId: the activities will be appended to the section. In this case\n * targetSectionId should not be present.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmids the list of cm ids to move\n * @param {number} targetSectionId the target section id\n * @param {number} targetCmId the target course module id\n */\n async cmMove(stateManager, cmids, targetSectionId, targetCmId) {\n if (!targetSectionId && !targetCmId) {\n throw new Error(`Mutation cmMove requires targetSectionId or targetCmId`);\n }\n const course = stateManager.get('course');\n this.cmLock(stateManager, cmids, true);\n const updates = await this._callEditWebservice('cm_move', course.id, cmids, targetSectionId, targetCmId);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.cmLock(stateManager, cmids, false);\n }\n\n /**\n * Move course modules to specific course location.\n *\n * @deprecated since Moodle 4.4 MDL-77038.\n * @todo MDL-80116 This will be deleted in Moodle 4.8.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids to move\n * @param {number} targetSectionId the target section id\n */\n async sectionMove(stateManager, sectionIds, targetSectionId) {\n log.debug('sectionMove() is deprecated. Use sectionMoveAfter() instead');\n if (!targetSectionId) {\n throw new Error(`Mutation sectionMove requires targetSectionId`);\n }\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice('section_move', course.id, sectionIds, targetSectionId);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n }\n\n /**\n * Move course modules after a specific course location.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids to move\n * @param {number} targetSectionId the target section id\n */\n async sectionMoveAfter(stateManager, sectionIds, targetSectionId) {\n if (!targetSectionId) {\n throw new Error(`Mutation sectionMoveAfter requires targetSectionId`);\n }\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice('section_move_after', course.id, sectionIds, targetSectionId);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n }\n\n /**\n * Add a new section to a specific course location.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {number} targetSectionId optional the target section id\n */\n async addSection(stateManager, targetSectionId) {\n if (!targetSectionId) {\n targetSectionId = 0;\n }\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('section_add', course.id, [], targetSectionId);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Delete sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of course modules ids\n */\n async sectionDelete(stateManager, sectionIds) {\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('section_delete', course.id, sectionIds);\n this.bulkReset(stateManager);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Delete cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of section ids\n */\n async cmDelete(stateManager, cmIds) {\n const course = stateManager.get('course');\n this.cmLock(stateManager, cmIds, true);\n const updates = await this._callEditWebservice('cm_delete', course.id, cmIds);\n this.bulkReset(stateManager);\n this.cmLock(stateManager, cmIds, false);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Add a new module to a specific course section.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {string} modName the modulename to add\n * @param {number} targetSectionNum the target section number\n * @param {number} targetCmId optional the target cm id\n */\n async addModule(stateManager, modName, targetSectionNum, targetCmId) {\n if (!modName) {\n throw new Error(`Mutation addModule requires moduleName`);\n }\n if (!targetSectionNum) {\n throw new Error(`Mutation addModule requires targetSectionNum`);\n }\n if (!targetCmId) {\n targetCmId = 0;\n }\n const course = stateManager.get('course');\n const updates = await this._callAddModuleWebservice(course.id, modName, targetSectionNum, targetCmId);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Add a new module to a specific course section.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {string} modName the modulename to add\n * @param {number} targetSectionId the target section id\n * @param {number} targetCmId optional the target cm id\n */\n async newModule(stateManager, modName, targetSectionId, targetCmId) {\n if (!modName) {\n throw new Error(`Mutation newModule requires moduleName`);\n }\n if (!targetSectionId) {\n throw new Error(`Mutation newModule requires targetSectionId`);\n }\n if (!targetCmId) {\n targetCmId = 0;\n }\n const course = stateManager.get('course');\n const updates = await this._callNewModuleWebservice(course.id, modName, targetSectionId, targetCmId);\n stateManager.processUpdates(updates);\n }\n\n /**\n * Mark or unmark course modules as dragging.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of course modules ids\n * @param {bool} dragValue the new dragging value\n */\n cmDrag(stateManager, cmIds, dragValue) {\n this.setPageItem(stateManager);\n this._setElementsValue(stateManager, 'cm', cmIds, 'dragging', dragValue);\n }\n\n /**\n * Mark or unmark course sections as dragging.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n * @param {bool} dragValue the new dragging value\n */\n sectionDrag(stateManager, sectionIds, dragValue) {\n this.setPageItem(stateManager);\n this._setElementsValue(stateManager, 'section', sectionIds, 'dragging', dragValue);\n }\n\n /**\n * Mark or unmark course modules as complete.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of course modules ids\n * @param {bool} complete the new completion value\n */\n async cmCompletion(stateManager, cmIds, complete) {\n const newState = (complete) ? 1 : 0;\n const action = (newState == 1) ? 'cm_complete' : 'cm_uncomplete';\n const logEntry = this._getLoggerEntry(stateManager, action, cmIds);\n stateManager.setReadOnly(false);\n cmIds.forEach((id) => {\n const element = stateManager.get('cm', id);\n if (element) {\n element.isoverallcomplete = complete;\n element.completionstate = newState;\n }\n });\n stateManager.setReadOnly(true);\n stateManager.addLoggerEntry(await logEntry);\n }\n\n /**\n * Move cms to the right: indent = 1.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmMoveRight(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_moveright', cmIds);\n }\n\n /**\n * Move cms to the left: indent = 0.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmMoveLeft(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_moveleft', cmIds);\n }\n\n /**\n * Set cms group mode to NOGROUPS.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmNoGroups(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_nogroups', cmIds);\n }\n\n /**\n * Set cms group mode to VISIBLEGROUPS.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmVisibleGroups(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_visiblegroups', cmIds);\n }\n\n /**\n * Set cms group mode to SEPARATEGROUPS.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n async cmSeparateGroups(stateManager, cmIds) {\n await this._cmBasicAction(stateManager, 'cm_separategroups', cmIds);\n }\n\n /**\n * Lock or unlock course modules.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of course modules ids\n * @param {bool} lockValue the new locked value\n */\n cmLock(stateManager, cmIds, lockValue) {\n this._setElementsValue(stateManager, 'cm', cmIds, 'locked', lockValue);\n }\n\n /**\n * Lock or unlock course sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n * @param {bool} lockValue the new locked value\n */\n sectionLock(stateManager, sectionIds, lockValue) {\n this._setElementsValue(stateManager, 'section', sectionIds, 'locked', lockValue);\n }\n\n _setElementsValue(stateManager, name, ids, fieldName, newValue) {\n stateManager.setReadOnly(false);\n ids.forEach((id) => {\n const element = stateManager.get(name, id);\n if (element) {\n element[fieldName] = newValue;\n }\n });\n stateManager.setReadOnly(true);\n }\n\n /**\n * Set the page current item.\n *\n * Only one element of the course state can be the page item at a time.\n *\n * There are several actions that can alter the page current item. For example, when the user is in an activity\n * page, the page item is always the activity one. However, in a course page, when the user scrolls to an element,\n * this element get the page item.\n *\n * If the page item is static means that it is not meant to change. This is important because\n * static page items has some special logic. For example, if a cm is the static page item\n * and it is inside a collapsed section, the course index will expand the section to make it visible.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {String|undefined} type the element type (section or cm). Undefined will remove the current page item.\n * @param {Number|undefined} id the element id\n * @param {boolean|undefined} isStatic if the page item is static\n */\n setPageItem(stateManager, type, id, isStatic) {\n let newPageItem;\n if (type !== undefined) {\n newPageItem = stateManager.get(type, id);\n if (!newPageItem) {\n return;\n }\n }\n stateManager.setReadOnly(false);\n // Remove the current page item.\n const course = stateManager.get('course');\n course.pageItem = null;\n // Save the new page item.\n if (newPageItem) {\n course.pageItem = {\n id,\n type,\n sectionId: (type == 'section') ? newPageItem.id : newPageItem.sectionid,\n isStatic,\n };\n }\n stateManager.setReadOnly(true);\n }\n\n /**\n * Unlock all course elements.\n *\n * @param {StateManager} stateManager the current state manager\n */\n unlockAll(stateManager) {\n const state = stateManager.state;\n stateManager.setReadOnly(false);\n state.section.forEach((section) => {\n section.locked = false;\n });\n state.cm.forEach((cm) => {\n cm.locked = false;\n });\n stateManager.setReadOnly(true);\n }\n\n /**\n * Update the course index collapsed attribute of some sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the affected section ids\n * @param {boolean} collapsed the new collapsed value\n */\n async sectionIndexCollapsed(stateManager, sectionIds, collapsed) {\n const affectedSections = this._updateStateSectionPreference(stateManager, 'indexcollapsed', sectionIds, collapsed);\n if (!affectedSections) {\n return;\n }\n const course = stateManager.get('course');\n let actionName = 'section_index_collapsed';\n if (!collapsed) {\n actionName = 'section_index_expanded';\n }\n await this._callEditWebservice(actionName, course.id, affectedSections);\n }\n\n /**\n * Update the course index collapsed attribute of all sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {boolean} collapsed the new collapsed value\n */\n async allSectionsIndexCollapsed(stateManager, collapsed) {\n const sectionIds = stateManager.getIds('section');\n this.sectionIndexCollapsed(stateManager, sectionIds, collapsed);\n }\n\n /**\n * Update the course content collapsed attribute of some sections.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the affected section ids\n * @param {boolean} collapsed the new collapsed value\n */\n async sectionContentCollapsed(stateManager, sectionIds, collapsed) {\n const affectedSections = this._updateStateSectionPreference(stateManager, 'contentcollapsed', sectionIds, collapsed);\n if (!affectedSections) {\n return;\n }\n const course = stateManager.get('course');\n let actionName = 'section_content_collapsed';\n if (!collapsed) {\n actionName = 'section_content_expanded';\n }\n await this._callEditWebservice(actionName, course.id, affectedSections);\n }\n\n /**\n * Private batch update for a section preference attribute.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {string} preferenceName the preference name\n * @param {array} sectionIds the affected section ids\n * @param {boolean} preferenceValue the new preferenceValue value\n * @return {Number[]|null} sections ids with the preference value true or null if no update is required\n */\n _updateStateSectionPreference(stateManager, preferenceName, sectionIds, preferenceValue) {\n stateManager.setReadOnly(false);\n const affectedSections = [];\n // Check if we need to update preferences.\n sectionIds.forEach(sectionId => {\n const section = stateManager.get('section', sectionId);\n if (section === undefined) {\n stateManager.setReadOnly(true);\n return null;\n }\n const newValue = preferenceValue ?? section[preferenceName];\n if (section[preferenceName] != newValue) {\n section[preferenceName] = newValue;\n affectedSections.push(section.id);\n }\n });\n stateManager.setReadOnly(true);\n return affectedSections;\n }\n\n /**\n * Enable/disable bulk editing.\n *\n * Note: reenabling the bulk will clean the current selection.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {Boolean} enabled the new bulk state.\n */\n bulkEnable(stateManager, enabled) {\n const state = stateManager.state;\n stateManager.setReadOnly(false);\n state.bulk.enabled = enabled;\n state.bulk.selectedType = '';\n state.bulk.selection = [];\n stateManager.setReadOnly(true);\n }\n\n /**\n * Reset the current selection.\n * @param {StateManager} stateManager the current state manager\n */\n bulkReset(stateManager) {\n const state = stateManager.state;\n stateManager.setReadOnly(false);\n state.bulk.selectedType = '';\n state.bulk.selection = [];\n stateManager.setReadOnly(true);\n }\n\n /**\n * Select a list of cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n cmSelect(stateManager, cmIds) {\n this._addIdsToSelection(stateManager, 'cm', cmIds);\n }\n\n /**\n * Unselect a list of cms.\n * @param {StateManager} stateManager the current state manager\n * @param {array} cmIds the list of cm ids\n */\n cmUnselect(stateManager, cmIds) {\n this._removeIdsFromSelection(stateManager, 'cm', cmIds);\n }\n\n /**\n * Select a list of sections.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of cm ids\n */\n sectionSelect(stateManager, sectionIds) {\n this._addIdsToSelection(stateManager, 'section', sectionIds);\n }\n\n /**\n * Unselect a list of sections.\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of cm ids\n */\n sectionUnselect(stateManager, sectionIds) {\n this._removeIdsFromSelection(stateManager, 'section', sectionIds);\n }\n\n /**\n * Add some ids to the current bulk selection.\n * @param {StateManager} stateManager the current state manager\n * @param {String} typeName the type name (section/cm)\n * @param {array} ids the list of ids\n */\n _addIdsToSelection(stateManager, typeName, ids) {\n const bulk = stateManager.state.bulk;\n if (!bulk?.enabled) {\n throw new Error(`Bulk is not enabled`);\n }\n if (bulk?.selectedType !== \"\" && bulk?.selectedType !== typeName) {\n throw new Error(`Cannot add ${typeName} to the current selection`);\n }\n\n // Stored ids are strings for compatability with HTML data attributes.\n ids = ids.map(value => value.toString());\n\n stateManager.setReadOnly(false);\n bulk.selectedType = typeName;\n const newSelection = new Set([...bulk.selection, ...ids]);\n bulk.selection = [...newSelection];\n stateManager.setReadOnly(true);\n }\n\n /**\n * Remove some ids to the current bulk selection.\n *\n * The method resets the selection type if the current selection is empty.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {String} typeName the type name (section/cm)\n * @param {array} ids the list of ids\n */\n _removeIdsFromSelection(stateManager, typeName, ids) {\n const bulk = stateManager.state.bulk;\n if (!bulk?.enabled) {\n throw new Error(`Bulk is not enabled`);\n }\n if (bulk?.selectedType !== \"\" && bulk?.selectedType !== typeName) {\n throw new Error(`Cannot remove ${typeName} from the current selection`);\n }\n\n // Stored ids are strings for compatability with HTML data attributes.\n ids = ids.map(value => value.toString());\n\n stateManager.setReadOnly(false);\n const IdsToFilter = new Set(ids);\n bulk.selection = bulk.selection.filter(current => !IdsToFilter.has(current));\n if (bulk.selection.length === 0) {\n bulk.selectedType = '';\n }\n stateManager.setReadOnly(true);\n }\n\n /**\n * Get updated state data related to some cm ids.\n *\n * @method cmState\n * @param {StateManager} stateManager the current state\n * @param {array} cmids the list of cm ids to update\n */\n async cmState(stateManager, cmids) {\n this.cmLock(stateManager, cmids, true);\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('cm_state', course.id, cmids);\n stateManager.processUpdates(updates);\n this.cmLock(stateManager, cmids, false);\n }\n\n /**\n * Get updated state data related to some section ids.\n *\n * @method sectionState\n * @param {StateManager} stateManager the current state\n * @param {array} sectionIds the list of section ids to update\n */\n async sectionState(stateManager, sectionIds) {\n this.sectionLock(stateManager, sectionIds, true);\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('section_state', course.id, sectionIds);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n }\n\n /**\n * Get the full updated state data of the course.\n *\n * @param {StateManager} stateManager the current state\n */\n async courseState(stateManager) {\n const course = stateManager.get('course');\n const updates = await this._callEditWebservice('course_state', course.id);\n stateManager.processUpdates(updates);\n }\n\n}\n"],"names":["isLoggerSet","action","courseId","ids","targetSectionId","targetCmId","args","courseid","targetsectionid","targetcmid","ajaxresult","ajax","call","methodname","JSON","parse","modName","targetSectionNum","modname","targetsectionnum","stateManager","sectionIds","logEntry","this","_getLoggerEntry","itemType","course","get","sectionLock","updates","_callEditWebservice","id","bulkReset","processUpdates","addLoggerEntry","cmIds","cmLock","itemIds","data","setLogger","SRLogger","feedbackParams","split","batch","length","count","itemInfo","name","title","targetSectionName","targetCmName","feedbackMessage","toLowerCase","component","init","addUpdateTypes","prepareFields","_prepareFields","updateName","fields","locked","_sectionBasicAction","_cmBasicAction","Set","add","forEach","cmId","cm","sectionid","Array","from","cmids","Error","debug","_callAddModuleWebservice","_callNewModuleWebservice","cmDrag","dragValue","setPageItem","_setElementsValue","sectionDrag","complete","newState","setReadOnly","element","isoverallcomplete","completionstate","lockValue","fieldName","newValue","type","isStatic","newPageItem","undefined","pageItem","sectionId","unlockAll","state","section","collapsed","affectedSections","_updateStateSectionPreference","actionName","getIds","sectionIndexCollapsed","preferenceName","preferenceValue","push","bulkEnable","enabled","bulk","selectedType","selection","cmSelect","_addIdsToSelection","cmUnselect","_removeIdsFromSelection","sectionSelect","sectionUnselect","typeName","map","value","toString","newSelection","IdsToFilter","filter","current","has"],"mappings":"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"} \ No newline at end of file diff --git a/course/format/amd/src/local/courseeditor/mutations.js b/course/format/amd/src/local/courseeditor/mutations.js index 0459fb65f8c..be8b6a7230b 100644 --- a/course/format/amd/src/local/courseeditor/mutations.js +++ b/course/format/amd/src/local/courseeditor/mutations.js @@ -518,8 +518,10 @@ export default class { * @param {array} cmIds the list of course modules ids * @param {bool} complete the new completion value */ - cmCompletion(stateManager, cmIds, complete) { + async cmCompletion(stateManager, cmIds, complete) { const newState = (complete) ? 1 : 0; + const action = (newState == 1) ? 'cm_complete' : 'cm_uncomplete'; + const logEntry = this._getLoggerEntry(stateManager, action, cmIds); stateManager.setReadOnly(false); cmIds.forEach((id) => { const element = stateManager.get('cm', id); @@ -529,6 +531,7 @@ export default class { } }); stateManager.setReadOnly(true); + stateManager.addLoggerEntry(await logEntry); } /** diff --git a/lang/en/courseformat.php b/lang/en/courseformat.php index dbdf1fea29d..dd761553f90 100644 --- a/lang/en/courseformat.php +++ b/lang/en/courseformat.php @@ -34,6 +34,8 @@ $string['bulkeditingcourse'] = 'Bulk edit course: {$a}'; $string['bulkcancel'] = 'Close bulk actions'; $string['bulkselection'] = '{$a} selected'; $string['bulkselection_plural'] = '{$a} selected'; +$string['cm_complete_feedback'] = '{$a->name} marked as completed.'; +$string['cm_complete_feedback_batch'] = 'Selected {$a->count} activities marked as completed.'; $string['cm_delete_feedback'] = '{$a->name} deleted.'; $string['cm_delete_feedback_batch'] = 'Selected {$a->count} activities deleted.'; $string['cm_duplicate_feedback'] = '{$a->name} duplicated.'; @@ -48,6 +50,8 @@ $string['cm_show_feedback'] = '{$a->name} is now shown.'; $string['cm_show_feedback_batch'] = 'The selected {$a->count} activities are now shown.'; $string['cm_stealth_feedback'] = '{$a->name} is now available but not shown on the course page.'; $string['cm_stealth_feedback_batch'] = 'The selected {$a->count} activities are now available but not shown on the course page.'; +$string['cm_uncomplete_feedback'] = '{$a->name} marked as uncompleted.'; +$string['cm_uncomplete_feedback_batch'] = 'Selected {$a->count} activities marked as uncompleted.'; $string['cm_visiblegroups_feedback'] = '{$a->name} group mode changed to Visible groups.'; $string['cmavailability'] = 'Activity availability'; $string['cmdelete_info'] = 'This will delete {$a->name} and any user data it contains.';