mirror of
https://github.com/moodle/moodle.git
synced 2025-04-20 07:56:06 +02:00
Merge branch 'MDL-79061-main-2' of https://github.com/junpataleta/moodle
This commit is contained in:
commit
39a7a380c9
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -14,7 +14,16 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ajax from 'core/ajax';
|
||||
import {getString} from "core/str";
|
||||
import log from 'core/log';
|
||||
import SRLogger from "core/local/reactive/srlogger";
|
||||
|
||||
/**
|
||||
* Flag to determine whether the screen reader-only logger has already been set, so we only need to set it once.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
let isLoggerSet = false;
|
||||
|
||||
/**
|
||||
* Default mutation manager
|
||||
@ -66,6 +75,11 @@ export default class {
|
||||
* @param {number} targetCmId optional target cm id (for moving actions)
|
||||
*/
|
||||
async _sectionBasicAction(stateManager, action, sectionIds, targetSectionId, targetCmId) {
|
||||
const logEntry = this._getLoggerEntry(stateManager, action, sectionIds, {
|
||||
targetSectionId,
|
||||
targetCmId,
|
||||
itemType: 'section',
|
||||
});
|
||||
const course = stateManager.get('course');
|
||||
this.sectionLock(stateManager, sectionIds, true);
|
||||
const updates = await this._callEditWebservice(
|
||||
@ -78,6 +92,7 @@ export default class {
|
||||
this.bulkReset(stateManager);
|
||||
stateManager.processUpdates(updates);
|
||||
this.sectionLock(stateManager, sectionIds, false);
|
||||
stateManager.addLoggerEntry(await logEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,6 +104,11 @@ export default class {
|
||||
* @param {number} targetCmId optional target cm id (for moving actions)
|
||||
*/
|
||||
async _cmBasicAction(stateManager, action, cmIds, targetSectionId, targetCmId) {
|
||||
const logEntry = this._getLoggerEntry(stateManager, action, cmIds, {
|
||||
targetSectionId,
|
||||
targetCmId,
|
||||
itemType: 'cm',
|
||||
});
|
||||
const course = stateManager.get('course');
|
||||
this.cmLock(stateManager, cmIds, true);
|
||||
const updates = await this._callEditWebservice(
|
||||
@ -101,6 +121,56 @@ export default class {
|
||||
this.bulkReset(stateManager);
|
||||
stateManager.processUpdates(updates);
|
||||
this.cmLock(stateManager, cmIds, false);
|
||||
stateManager.addLoggerEntry(await logEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log entry for the current action.
|
||||
* @param {StateManager} stateManager the current state manager
|
||||
* @param {string} action the action name
|
||||
* @param {int[]|null} itemIds the element ids
|
||||
* @param {Object|undefined} data extra params for the log entry
|
||||
* @param {string|undefined} data.itemType the element type (will be taken from action if none)
|
||||
* @param {int|null|undefined} data.targetSectionId the target section id
|
||||
* @param {int|null|undefined} data.targetCmId the target cm id
|
||||
* @param {String|null|undefined} data.component optional component (for format plugins)
|
||||
* @return {Object} the log entry
|
||||
*/
|
||||
async _getLoggerEntry(stateManager, action, itemIds, data = {}) {
|
||||
if (!isLoggerSet) {
|
||||
// In case the logger has not been set from init(), ensure we set the logger.
|
||||
stateManager.setLogger(new SRLogger());
|
||||
isLoggerSet = true;
|
||||
}
|
||||
const feedbackParams = {
|
||||
action,
|
||||
itemType: data.itemType ?? action.split('_')[0],
|
||||
};
|
||||
let batch = '';
|
||||
if (itemIds.length > 1) {
|
||||
feedbackParams.count = itemIds.length;
|
||||
batch = '_batch';
|
||||
} else if (itemIds.length === 1) {
|
||||
const itemInfo = stateManager.get(feedbackParams.itemType, itemIds[0]);
|
||||
feedbackParams.name = itemInfo.title ?? itemInfo.name;
|
||||
// Apply shortener for modules like label.
|
||||
}
|
||||
if (data.targetSectionId) {
|
||||
feedbackParams.targetSectionName = stateManager.get('section', data.targetSectionId).title;
|
||||
}
|
||||
if (data.targetCmId) {
|
||||
feedbackParams.targetCmName = stateManager.get('cm', data.targetCmId).name;
|
||||
}
|
||||
|
||||
const message = await getString(
|
||||
`${action.toLowerCase()}_feedback${batch}`,
|
||||
data.component ?? 'core_courseformat',
|
||||
feedbackParams
|
||||
);
|
||||
|
||||
return {
|
||||
feedbackMessage: message,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,10 +181,13 @@ export default class {
|
||||
* @param {StateManager} stateManager the state manager
|
||||
*/
|
||||
init(stateManager) {
|
||||
// Add a method to prepare the fields when some update is comming from the server.
|
||||
// Add a method to prepare the fields when some update is coming from the server.
|
||||
stateManager.addUpdateTypes({
|
||||
prepareFields: this._prepareFields,
|
||||
});
|
||||
// Use the screen reader-only logger (SRLogger) to handle the feedback messages from the mutations.
|
||||
stateManager.setLogger(new SRLogger());
|
||||
isLoggerSet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,6 +259,7 @@ export default class {
|
||||
* @param {number|undefined} targetCmId the target course module id
|
||||
*/
|
||||
async cmDuplicate(stateManager, cmIds, targetSectionId, targetCmId) {
|
||||
const logEntry = this._getLoggerEntry(stateManager, 'cm_duplicate', cmIds);
|
||||
const course = stateManager.get('course');
|
||||
// Lock all target sections.
|
||||
const sectionIds = new Set();
|
||||
@ -204,6 +278,7 @@ export default class {
|
||||
stateManager.processUpdates(updates);
|
||||
|
||||
this.sectionLock(stateManager, Array.from(sectionIds), false);
|
||||
stateManager.addLoggerEntry(await logEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,3 +1,3 @@
|
||||
define("format_topics/mutations",["exports","core_courseformat/courseeditor","core_courseformat/local/courseeditor/mutations","core_courseformat/local/content/actions"],(function(_exports,_courseeditor,_mutations,_actions){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_mutations=_interopRequireDefault(_mutations),_actions=_interopRequireDefault(_actions);class TopicsMutations extends _mutations.default{constructor(){super(...arguments),_defineProperty(this,"sectionHighlight",(async function(stateManager,sectionIds){const course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice("section_highlight",course.id,sectionIds);stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1)})),_defineProperty(this,"sectionUnhighlight",(async function(stateManager,sectionIds){const course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice("section_unhighlight",course.id,sectionIds);stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1)}))}}_exports.init=()=>{(0,_courseeditor.getCurrentCourseEditor)().addMutations(new TopicsMutations),_actions.default.addActions({sectionHighlight:"sectionHighlight",sectionUnhighlight:"sectionUnhighlight"})}}));
|
||||
define("format_topics/mutations",["exports","core_courseformat/courseeditor","core_courseformat/local/courseeditor/mutations","core_courseformat/local/content/actions"],(function(_exports,_courseeditor,_mutations,_actions){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_mutations=_interopRequireDefault(_mutations),_actions=_interopRequireDefault(_actions);class TopicsMutations extends _mutations.default{constructor(){super(...arguments),_defineProperty(this,"sectionHighlight",(async function(stateManager,sectionIds){const logEntry=this._getLoggerEntry(stateManager,"section_highlight",sectionIds,{component:"format_topics"}),course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice("section_highlight",course.id,sectionIds);stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1),stateManager.addLoggerEntry(await logEntry)})),_defineProperty(this,"sectionUnhighlight",(async function(stateManager,sectionIds){const logEntry=this._getLoggerEntry(stateManager,"section_unhighlight",sectionIds,{component:"format_topics"}),course=stateManager.get("course");this.sectionLock(stateManager,sectionIds,!0);const updates=await this._callEditWebservice("section_unhighlight",course.id,sectionIds);stateManager.processUpdates(updates),this.sectionLock(stateManager,sectionIds,!1),stateManager.addLoggerEntry(await logEntry)}))}}_exports.init=()=>{(0,_courseeditor.getCurrentCourseEditor)().addMutations(new TopicsMutations),_actions.default.addActions({sectionHighlight:"sectionHighlight",sectionUnhighlight:"sectionUnhighlight"})}}));
|
||||
|
||||
//# sourceMappingURL=mutations.min.js.map
|
@ -1 +1 @@
|
||||
{"version":3,"file":"mutations.min.js","sources":["../src/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 <http://www.gnu.org/licenses/>.\n\n/**\n * Format topics mutations.\n *\n * An instance of this class will be used to add custom mutations to the course editor.\n * To make sure the addMutations method find the proper functions, all functions must\n * be declared as class attributes, not a simple methods. The reason is because many\n * plugins can add extra mutations to the course editor.\n *\n * @module format_topics/mutations\n * @copyright 2022 Ferran Recio <ferran@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getCurrentCourseEditor} from 'core_courseformat/courseeditor';\nimport DefaultMutations from 'core_courseformat/local/courseeditor/mutations';\nimport CourseActions from 'core_courseformat/local/content/actions';\n\nclass TopicsMutations extends DefaultMutations {\n\n /**\n * Highlight sections.\n *\n * It is important to note this mutation method is declared as a class attribute,\n * See the class jsdoc for more details on why.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n */\n sectionHighlight = async function(stateManager, sectionIds) {\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice('section_highlight', course.id, sectionIds);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n };\n\n /**\n * Unhighlight sections.\n *\n * It is important to note this mutation method is declared as a class attribute,\n * See the class jsdoc for more details on why.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n */\n sectionUnhighlight = async function(stateManager, sectionIds) {\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice('section_unhighlight', course.id, sectionIds);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n };\n}\n\nexport const init = () => {\n const courseEditor = getCurrentCourseEditor();\n // Some plugin (activity or block) may have their own mutations already registered.\n // This is why we use addMutations instead of setMutations here.\n courseEditor.addMutations(new TopicsMutations());\n // Add direct mutation content actions.\n CourseActions.addActions({\n sectionHighlight: 'sectionHighlight',\n sectionUnhighlight: 'sectionUnhighlight',\n });\n};\n"],"names":["TopicsMutations","DefaultMutations","async","stateManager","sectionIds","course","get","sectionLock","updates","this","_callEditWebservice","id","processUpdates","addMutations","addActions","sectionHighlight","sectionUnhighlight"],"mappings":"goBAgCMA,wBAAwBC,8FAWPC,eAAeC,aAAcC,kBACtCC,OAASF,aAAaG,IAAI,eAC3BC,YAAYJ,aAAcC,YAAY,SACrCI,cAAgBC,KAAKC,oBAAoB,oBAAqBL,OAAOM,GAAIP,YAC/ED,aAAaS,eAAeJ,cACvBD,YAAYJ,aAAcC,YAAY,iDAY1BF,eAAeC,aAAcC,kBACxCC,OAASF,aAAaG,IAAI,eAC3BC,YAAYJ,aAAcC,YAAY,SACrCI,cAAgBC,KAAKC,oBAAoB,sBAAuBL,OAAOM,GAAIP,YACjFD,aAAaS,eAAeJ,cACvBD,YAAYJ,aAAcC,YAAY,qBAI/B,MACK,0CAGRS,aAAa,IAAIb,kCAEhBc,WAAW,CACrBC,iBAAkB,mBAClBC,mBAAoB"}
|
||||
{"version":3,"file":"mutations.min.js","sources":["../src/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 <http://www.gnu.org/licenses/>.\n\n/**\n * Format topics mutations.\n *\n * An instance of this class will be used to add custom mutations to the course editor.\n * To make sure the addMutations method find the proper functions, all functions must\n * be declared as class attributes, not a simple methods. The reason is because many\n * plugins can add extra mutations to the course editor.\n *\n * @module format_topics/mutations\n * @copyright 2022 Ferran Recio <ferran@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {getCurrentCourseEditor} from 'core_courseformat/courseeditor';\nimport DefaultMutations from 'core_courseformat/local/courseeditor/mutations';\nimport CourseActions from 'core_courseformat/local/content/actions';\n\nclass TopicsMutations extends DefaultMutations {\n\n /**\n * Highlight sections.\n *\n * It is important to note this mutation method is declared as a class attribute,\n * See the class jsdoc for more details on why.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n */\n sectionHighlight = async function(stateManager, sectionIds) {\n const logEntry = this._getLoggerEntry(\n stateManager,\n 'section_highlight',\n sectionIds,\n {component: 'format_topics'}\n );\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice('section_highlight', course.id, sectionIds);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n stateManager.addLoggerEntry(await logEntry);\n\n };\n\n /**\n * Unhighlight sections.\n *\n * It is important to note this mutation method is declared as a class attribute,\n * See the class jsdoc for more details on why.\n *\n * @param {StateManager} stateManager the current state manager\n * @param {array} sectionIds the list of section ids\n */\n sectionUnhighlight = async function(stateManager, sectionIds) {\n const logEntry = this._getLoggerEntry(\n stateManager,\n 'section_unhighlight',\n sectionIds,\n {component: 'format_topics'}\n );\n const course = stateManager.get('course');\n this.sectionLock(stateManager, sectionIds, true);\n const updates = await this._callEditWebservice('section_unhighlight', course.id, sectionIds);\n stateManager.processUpdates(updates);\n this.sectionLock(stateManager, sectionIds, false);\n stateManager.addLoggerEntry(await logEntry);\n };\n}\n\nexport const init = () => {\n const courseEditor = getCurrentCourseEditor();\n // Some plugin (activity or block) may have their own mutations already registered.\n // This is why we use addMutations instead of setMutations here.\n courseEditor.addMutations(new TopicsMutations());\n // Add direct mutation content actions.\n CourseActions.addActions({\n sectionHighlight: 'sectionHighlight',\n sectionUnhighlight: 'sectionUnhighlight',\n });\n};\n"],"names":["TopicsMutations","DefaultMutations","async","stateManager","sectionIds","logEntry","this","_getLoggerEntry","component","course","get","sectionLock","updates","_callEditWebservice","id","processUpdates","addLoggerEntry","addMutations","addActions","sectionHighlight","sectionUnhighlight"],"mappings":"goBAgCMA,wBAAwBC,8FAWPC,eAAeC,aAAcC,kBACtCC,SAAWC,KAAKC,gBAClBJ,aACA,oBACAC,WACA,CAACI,UAAW,kBAEVC,OAASN,aAAaO,IAAI,eAC3BC,YAAYR,aAAcC,YAAY,SACrCQ,cAAgBN,KAAKO,oBAAoB,oBAAqBJ,OAAOK,GAAIV,YAC/ED,aAAaY,eAAeH,cACvBD,YAAYR,aAAcC,YAAY,GAC3CD,aAAaa,qBAAqBX,wDAajBH,eAAeC,aAAcC,kBACxCC,SAAWC,KAAKC,gBAClBJ,aACA,sBACAC,WACA,CAACI,UAAW,kBAEVC,OAASN,aAAaO,IAAI,eAC3BC,YAAYR,aAAcC,YAAY,SACrCQ,cAAgBN,KAAKO,oBAAoB,sBAAuBJ,OAAOK,GAAIV,YACjFD,aAAaY,eAAeH,cACvBD,YAAYR,aAAcC,YAAY,GAC3CD,aAAaa,qBAAqBX,4BAItB,MACK,0CAGRY,aAAa,IAAIjB,kCAEhBkB,WAAW,CACrBC,iBAAkB,mBAClBC,mBAAoB"}
|
@ -42,11 +42,19 @@ class TopicsMutations extends DefaultMutations {
|
||||
* @param {array} sectionIds the list of section ids
|
||||
*/
|
||||
sectionHighlight = async function(stateManager, sectionIds) {
|
||||
const logEntry = this._getLoggerEntry(
|
||||
stateManager,
|
||||
'section_highlight',
|
||||
sectionIds,
|
||||
{component: 'format_topics'}
|
||||
);
|
||||
const course = stateManager.get('course');
|
||||
this.sectionLock(stateManager, sectionIds, true);
|
||||
const updates = await this._callEditWebservice('section_highlight', course.id, sectionIds);
|
||||
stateManager.processUpdates(updates);
|
||||
this.sectionLock(stateManager, sectionIds, false);
|
||||
stateManager.addLoggerEntry(await logEntry);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -59,11 +67,18 @@ class TopicsMutations extends DefaultMutations {
|
||||
* @param {array} sectionIds the list of section ids
|
||||
*/
|
||||
sectionUnhighlight = async function(stateManager, sectionIds) {
|
||||
const logEntry = this._getLoggerEntry(
|
||||
stateManager,
|
||||
'section_unhighlight',
|
||||
sectionIds,
|
||||
{component: 'format_topics'}
|
||||
);
|
||||
const course = stateManager.get('course');
|
||||
this.sectionLock(stateManager, sectionIds, true);
|
||||
const updates = await this._callEditWebservice('section_unhighlight', course.id, sectionIds);
|
||||
stateManager.processUpdates(updates);
|
||||
this.sectionLock(stateManager, sectionIds, false);
|
||||
stateManager.addLoggerEntry(await logEntry);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,8 @@ $string['pluginname'] = 'Topics format';
|
||||
$string['privacy:metadata'] = 'The Topics format plugin does not store any personal data.';
|
||||
$string['indentation'] = 'Allow indentation on course page';
|
||||
$string['indentation_help'] = 'Allow teachers, and other users with the manage activities capability, to indent items on the course page.';
|
||||
$string['section_highlight_feedback'] = 'Section {$a->name} is highlighted.';
|
||||
$string['section_unhighlight_feedback'] = 'Highlight removed from section {$a->name}.';
|
||||
$string['section0name'] = 'General';
|
||||
$string['sectionavailability_title'] = 'Topic availability';
|
||||
$string['sectiondelete_title'] = 'Delete topic?';
|
||||
|
@ -33,6 +33,20 @@ $string['bulkeditingcourse'] = 'Bulk edit course: {$a}';
|
||||
$string['bulkcancel'] = 'Close bulk actions';
|
||||
$string['bulkselection'] = '{$a} selected';
|
||||
$string['bulkselection_plural'] = '{$a} selected';
|
||||
$string['cm_delete_feedback'] = '{$a->name} has been deleted.';
|
||||
$string['cm_delete_feedback_batch'] = 'The selected {$a->count} activities have been deleted.';
|
||||
$string['cm_duplicate_feedback'] = '{$a->name} has been duplicated.';
|
||||
$string['cm_duplicate_feedback_batch'] = 'The selected {$a->count} activities have been duplicated.';
|
||||
$string['cm_hide_feedback'] = '{$a->name} is now hidden.';
|
||||
$string['cm_hide_feedback_batch'] = 'The selected {$a->count} activities are now hidden.';
|
||||
$string['cm_moveleft_feedback'] = '{$a->name} has been moved to the left.';
|
||||
$string['cm_moveright_feedback'] = '{$a->name} has been moved to the right.';
|
||||
$string['cm_nogroups_feedback'] = '{$a->name}\'s group mode has been changed to "No groups".';
|
||||
$string['cm_separategroups_feedback'] = '{$a->name}\'s group mode has been changed to "Separate groups".';
|
||||
$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_visiblegroups_feedback'] = '{$a->name}\'s group mode has been changed to "Visible groups".';
|
||||
$string['cmavailability'] = 'Activity availability';
|
||||
$string['cmdelete_info'] = 'This will delete {$a->name} and any user data it contains.';
|
||||
$string['cmdelete_title'] = 'Delete activity?';
|
||||
@ -50,6 +64,12 @@ $string['courseindexoptions'] = 'Course index options';
|
||||
$string['nobulkaction'] = 'No bulk actions available';
|
||||
$string['preference:coursesectionspreferences'] = 'Section user preferences for course {$a}';
|
||||
$string['privacy:metadata:preference:coursesectionspreferences'] = 'Section user preferences like collapsed and expanded.';
|
||||
$string['section_hide_feedback'] = 'The course section {$a->name} has been hidden.';
|
||||
$string['section_hide_feedback_batch'] = 'The selected {$a->count} course sections have been hidden.';
|
||||
$string['section_show_feedback'] = 'The course section {$a->name} has been shown.';
|
||||
$string['section_show_feedback_batch'] = 'The selected {$a->count} course sections have been shown.';
|
||||
$string['section_delete_feedback'] = 'The course section {$a->name} has been deleted';
|
||||
$string['section_delete_feedback_batch'] = 'The selected {$a->count} course sections have been deleted';
|
||||
$string['sectionavailability_title'] = 'Section availability';
|
||||
$string['sectiondelete_info'] = 'This will delete {$a->name} and all the activities it contains.';
|
||||
$string['sectiondelete_title'] = 'Delete section?';
|
||||
|
17
lib/amd/build/local/reactive/logger.min.js
vendored
Normal file
17
lib/amd/build/local/reactive/logger.min.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
define("core/local/reactive/logger",["exports","core/toast"],(function(_exports,_toast){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0;return _exports.default=
|
||||
/**
|
||||
* Default reactive mutations logger class.
|
||||
*
|
||||
* This logger is used by default by the StateManager to log mutation feedbacks
|
||||
* and actions. By default, feedbacks will be displayed as a toast. However, the
|
||||
* reactive instance can provide alternative loggers to provide advanced logging
|
||||
* capabilities.
|
||||
*
|
||||
* @module core/local/reactive/logger
|
||||
* @class Logger
|
||||
* @copyright 2023 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class{constructor(){this._debug=!1}add(entry){entry.feedbackMessage&&(0,_toast.add)(entry.feedbackMessage)}},_exports.default}));
|
||||
|
||||
//# sourceMappingURL=logger.min.js.map
|
1
lib/amd/build/local/reactive/logger.min.js.map
Normal file
1
lib/amd/build/local/reactive/logger.min.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"logger.min.js","sources":["../../../src/local/reactive/logger.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Default reactive mutations logger class.\n *\n * This logger is used by default by the StateManager to log mutation feedbacks\n * and actions. By default, feedbacks will be displayed as a toast. However, the\n * reactive instance can provide alternative loggers to provide advanced logging\n * capabilities.\n *\n * @module core/local/reactive/logger\n * @class Logger\n * @copyright 2023 Ferran Recio <ferran@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Logger entry structure.\n *\n * @typedef {object} LoggerEntry\n * @property {string} feedbackMessage Feedback message.\n */\n\nimport {add as addToast} from 'core/toast';\n\n/**\n * Default reactive mutations logger class.\n * @class Logger\n */\nexport default class Logger {\n /**\n * Constructor.\n */\n constructor() {\n this._debug = false;\n }\n\n /**\n * Add a log entry.\n * @param {LoggerEntry} entry Log entry.\n */\n add(entry) {\n if (entry.feedbackMessage) {\n addToast(entry.feedbackMessage);\n }\n }\n}\n"],"names":["constructor","_debug","add","entry","feedbackMessage"],"mappings":";;;;;;;;;;;;;;MA8CIA,mBACSC,QAAS,EAOlBC,IAAIC,OACIA,MAAMC,gCACGD,MAAMC"}
|
3
lib/amd/build/local/reactive/srlogger.min.js
vendored
Normal file
3
lib/amd/build/local/reactive/srlogger.min.js
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
define("core/local/reactive/srlogger",["exports","core/local/reactive/logger"],(function(_exports,_logger){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_logger=(obj=_logger)&&obj.__esModule?obj:{default:obj};class SRLogger extends _logger.default{add(entry){if(entry.feedbackMessage){let loggerFeedback=document.getElementById(SRLogger.liveRegionId);loggerFeedback||(loggerFeedback=document.createElement("div"),loggerFeedback.id=SRLogger.liveRegionId,loggerFeedback.classList.add("sr-only"),loggerFeedback.setAttribute("aria-live","polite"),document.body.append(loggerFeedback)),loggerFeedback.innerHTML=entry.feedbackMessage,setTimeout((()=>{loggerFeedback.innerHTML=""}),4e3)}}}return _exports.default=SRLogger,function(obj,key,value){key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}(SRLogger,"liveRegionId","sr-logger-feedback-container"),_exports.default}));
|
||||
|
||||
//# sourceMappingURL=srlogger.min.js.map
|
1
lib/amd/build/local/reactive/srlogger.min.js.map
Normal file
1
lib/amd/build/local/reactive/srlogger.min.js.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"srlogger.min.js","sources":["../../../src/local/reactive/srlogger.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 <http://www.gnu.org/licenses/>.\n\n/**\n * Screen reader-only (sr-only) reactive mutations logger class.\n *\n * This logger can be used by the StateManager to log mutation feedbacks and actions.\n * The feedback messages logged by this logger will be rendered in a sr-only, ARIA live region.\n *\n * @module core/local/reactive/srlogger\n * @class SRLogger\n * @copyright 2023 Jun Pataleta <jun@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Logger from 'core/local/reactive/logger';\n\n/**\n * Logger entry structure.\n *\n * @typedef {object} LoggerEntry\n * @property {string} feedbackMessage Feedback message.\n */\n\n/**\n * Screen reader-only (sr-only) reactive mutations logger class.\n *\n * @class SRLogger\n */\nexport default class SRLogger extends Logger {\n /**\n * The element ID of the ARIA live region where the logger feedback will be rendered.\n *\n * @type {string}\n */\n static liveRegionId = 'sr-logger-feedback-container';\n\n /**\n * Add a log entry.\n * @param {LoggerEntry} entry Log entry.\n */\n add(entry) {\n if (entry.feedbackMessage) {\n // Fetch or create an ARIA live region that will serve as the container for the logger feedback.\n let loggerFeedback = document.getElementById(SRLogger.liveRegionId);\n if (!loggerFeedback) {\n loggerFeedback = document.createElement('div');\n loggerFeedback.id = SRLogger.liveRegionId;\n loggerFeedback.classList.add('sr-only');\n loggerFeedback.setAttribute('aria-live', 'polite');\n document.body.append(loggerFeedback);\n }\n // Set the ARIA live region's contents with the feedback.\n loggerFeedback.innerHTML = entry.feedbackMessage;\n\n // Clear the feedback message after 4 seconds to avoid the contents from being read out in case the user navigates\n // to this region. This is similar to the default timeout of toast messages before disappearing from view.\n setTimeout(() => {\n loggerFeedback.innerHTML = '';\n }, 4000);\n }\n }\n}\n"],"names":["SRLogger","Logger","add","entry","feedbackMessage","loggerFeedback","document","getElementById","liveRegionId","createElement","id","classList","setAttribute","body","append","innerHTML","setTimeout"],"mappings":"iQAyCqBA,iBAAiBC,gBAYlCC,IAAIC,UACIA,MAAMC,gBAAiB,KAEnBC,eAAiBC,SAASC,eAAeP,SAASQ,cACjDH,iBACDA,eAAiBC,SAASG,cAAc,OACxCJ,eAAeK,GAAKV,SAASQ,aAC7BH,eAAeM,UAAUT,IAAI,WAC7BG,eAAeO,aAAa,YAAa,UACzCN,SAASO,KAAKC,OAAOT,iBAGzBA,eAAeU,UAAYZ,MAAMC,gBAIjCY,YAAW,KACPX,eAAeU,UAAY,KAC5B,kLA9BMf,wBAMK"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
60
lib/amd/src/local/reactive/logger.js
Normal file
60
lib/amd/src/local/reactive/logger.js
Normal file
@ -0,0 +1,60 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Default reactive mutations logger class.
|
||||
*
|
||||
* This logger is used by default by the StateManager to log mutation feedbacks
|
||||
* and actions. By default, feedbacks will be displayed as a toast. However, the
|
||||
* reactive instance can provide alternative loggers to provide advanced logging
|
||||
* capabilities.
|
||||
*
|
||||
* @module core/local/reactive/logger
|
||||
* @class Logger
|
||||
* @copyright 2023 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Logger entry structure.
|
||||
*
|
||||
* @typedef {object} LoggerEntry
|
||||
* @property {string} feedbackMessage Feedback message.
|
||||
*/
|
||||
|
||||
import {add as addToast} from 'core/toast';
|
||||
|
||||
/**
|
||||
* Default reactive mutations logger class.
|
||||
* @class Logger
|
||||
*/
|
||||
export default class Logger {
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
constructor() {
|
||||
this._debug = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a log entry.
|
||||
* @param {LoggerEntry} entry Log entry.
|
||||
*/
|
||||
add(entry) {
|
||||
if (entry.feedbackMessage) {
|
||||
addToast(entry.feedbackMessage);
|
||||
}
|
||||
}
|
||||
}
|
75
lib/amd/src/local/reactive/srlogger.js
Normal file
75
lib/amd/src/local/reactive/srlogger.js
Normal file
@ -0,0 +1,75 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Screen reader-only (sr-only) reactive mutations logger class.
|
||||
*
|
||||
* This logger can be used by the StateManager to log mutation feedbacks and actions.
|
||||
* The feedback messages logged by this logger will be rendered in a sr-only, ARIA live region.
|
||||
*
|
||||
* @module core/local/reactive/srlogger
|
||||
* @class SRLogger
|
||||
* @copyright 2023 Jun Pataleta <jun@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import Logger from 'core/local/reactive/logger';
|
||||
|
||||
/**
|
||||
* Logger entry structure.
|
||||
*
|
||||
* @typedef {object} LoggerEntry
|
||||
* @property {string} feedbackMessage Feedback message.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Screen reader-only (sr-only) reactive mutations logger class.
|
||||
*
|
||||
* @class SRLogger
|
||||
*/
|
||||
export default class SRLogger extends Logger {
|
||||
/**
|
||||
* The element ID of the ARIA live region where the logger feedback will be rendered.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
static liveRegionId = 'sr-logger-feedback-container';
|
||||
|
||||
/**
|
||||
* Add a log entry.
|
||||
* @param {LoggerEntry} entry Log entry.
|
||||
*/
|
||||
add(entry) {
|
||||
if (entry.feedbackMessage) {
|
||||
// Fetch or create an ARIA live region that will serve as the container for the logger feedback.
|
||||
let loggerFeedback = document.getElementById(SRLogger.liveRegionId);
|
||||
if (!loggerFeedback) {
|
||||
loggerFeedback = document.createElement('div');
|
||||
loggerFeedback.id = SRLogger.liveRegionId;
|
||||
loggerFeedback.classList.add('sr-only');
|
||||
loggerFeedback.setAttribute('aria-live', 'polite');
|
||||
document.body.append(loggerFeedback);
|
||||
}
|
||||
// Set the ARIA live region's contents with the feedback.
|
||||
loggerFeedback.innerHTML = entry.feedbackMessage;
|
||||
|
||||
// Clear the feedback message after 4 seconds to avoid the contents from being read out in case the user navigates
|
||||
// to this region. This is similar to the default timeout of toast messages before disappearing from view.
|
||||
setTimeout(() => {
|
||||
loggerFeedback.innerHTML = '';
|
||||
}, 4000);
|
||||
}
|
||||
}
|
||||
}
|
@ -30,6 +30,8 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
import Logger from 'core/local/reactive/logger';
|
||||
|
||||
/**
|
||||
* State manager class.
|
||||
*
|
||||
@ -120,6 +122,8 @@ export default class StateManager {
|
||||
};
|
||||
this.target.addEventListener('state:loaded', initialStateDone);
|
||||
});
|
||||
|
||||
this.logger = new Logger();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -443,6 +447,24 @@ export default class StateManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the logger class instance.
|
||||
*
|
||||
* Reactive instances can provide alternative loggers to provide advanced logging.
|
||||
* @param {Logger} logger
|
||||
*/
|
||||
setLogger(logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new log entry into the reactive logger.
|
||||
* @param {LoggerEntry} entry
|
||||
*/
|
||||
addLoggerEntry(entry) {
|
||||
this.logger.add(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an element from the state or form an alternative state object.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user