first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
define("block_accessreview/module",["exports","core/ajax","core/templates","core/notification"],(function(_exports,_ajax,Templates,_notification){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,Templates=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}
/**
* Manager for the accessreview block.
*
* @module block_accessreview/module
* @author Max Larkin <max@brickfieldlabs.ie>
* @copyright 2020 Brickfield Education Labs <max@brickfieldlabs.ie>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/(Templates);let toggleState=!0;const renderTemplate=(element,errorCount,checkCount,displayFormat,minViews,viewDelta)=>{const weight=parseInt((errorCount-minViews)/viewDelta*2),context={resultPassed:!errorCount,classList:"",passRate:{errorCount:errorCount,checkCount:checkCount,failureRate:Math.round(errorCount/checkCount*100)}};if(!element)return Promise.resolve();const elementClassList=["block_accessreview"];context.resultPassed?elementClassList.push("block_accessreview_success"):weight?elementClassList.push("block_accessreview_danger"):elementClassList.push("block_accessreview_warning");const showIcons="showicons"==displayFormat||"showboth"==displayFormat,showBackground="showbackground"==displayFormat||"showboth"==displayFormat;return showBackground&&!showIcons?(element.classList.add(...elementClassList,"alert"),Promise.resolve()):(showIcons&&!showBackground&&(context.classList=elementClassList.join(" ")),Templates.renderForPromise("block_accessreview/status",context).then((_ref=>{let{html:html,js:js}=_ref;Templates.appendNodeContents(element,html,js),showBackground&&element.classList.add(...elementClassList,"alert")})).catch())},showAccessMap=function(courseId,displayFormat){let updatePreference=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return Promise.all(fetchReviewData(courseId,updatePreference)).then((_ref2=>{let[sectionData,moduleData]=_ref2;const{minViews:minViews,viewDelta:viewDelta}=getErrorTotals(sectionData,moduleData);return sectionData.forEach((section=>{const element=document.querySelector("#section-".concat(section.section," .summary"));element&&renderTemplate(element,section.numerrors,section.numchecks,displayFormat,minViews,viewDelta)})),moduleData.forEach((module=>{const element=document.getElementById("module-".concat(module.cmid));element&&renderTemplate(element,module.numerrors,module.numchecks,displayFormat,minViews,viewDelta)})),document.querySelector(".icon-accessmap").classList.remove("fa-eye-slash"),document.querySelector(".icon-accessmap").classList.add("fa-eye"),{sectionData:sectionData,moduleData:moduleData}})).catch(_notification.exception)},toggleAccessMap=(courseId,displayFormat)=>{toggleState=!toggleState,toggleState?showAccessMap(courseId,displayFormat,!0):function(){let updatePreference=arguments.length>0&&void 0!==arguments[0]&&arguments[0];document.querySelectorAll(".block_accessreview_view").forEach((node=>node.remove()));const classList=["block_accessreview","block_accessreview_success","block_accessreview_warning","block_accessreview_danger","block_accessreview_view","alert"];document.querySelectorAll(".block_accessreview").forEach((node=>node.classList.remove(...classList))),updatePreference&&setToggleStatePreference(!1),document.querySelector(".icon-accessmap").classList.remove("fa-eye"),document.querySelector(".icon-accessmap").classList.add("fa-eye-slash")}(!0)},getErrorTotals=(sectionData,moduleData)=>{const totals={totalErrors:0,totalUsers:0,minViews:0,maxViews:0,viewDelta:0};return[].concat(sectionData,moduleData).forEach((item=>{totals.totalErrors+=item.numerrors,item.numerrors<totals.minViews&&(totals.minViews=item.numerrors),item.numerrors>totals.maxViews&&(totals.maxViews=item.numerrors),totals.totalUsers+=item.numchecks})),totals.viewDelta=totals.maxViews-totals.minViews+1,totals},getTogglePreferenceParams=toggleState=>({methodname:"core_user_update_user_preferences",args:{preferences:[{type:"block_accessreviewtogglestate",value:toggleState}]}}),setToggleStatePreference=toggleState=>(0,_ajax.call)([getTogglePreferenceParams(toggleState)]),fetchReviewData=function(courseid){let updatePreference=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const calls=[{methodname:"block_accessreview_get_section_data",args:{courseid:courseid}},{methodname:"block_accessreview_get_module_data",args:{courseid:courseid}}];return updatePreference&&calls.push(getTogglePreferenceParams(!0)),(0,_ajax.call)(calls)};_exports.init=(toggled,displayFormat,courseId)=>{toggleState=1==toggled,toggleState&&showAccessMap(courseId,displayFormat),((courseId,displayFormat)=>{document.addEventListener("click",(e=>{e.target.closest("#toggle-accessmap")&&(e.preventDefault(),toggleAccessMap(courseId,displayFormat))}))})(courseId,displayFormat)}}));
//# sourceMappingURL=module.min.js.map
File diff suppressed because one or more lines are too long
+303
View File
@@ -0,0 +1,303 @@
// 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/>.
/**
* Manager for the accessreview block.
*
* @module block_accessreview/module
* @author Max Larkin <max@brickfieldlabs.ie>
* @copyright 2020 Brickfield Education Labs <max@brickfieldlabs.ie>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import {call as fetchMany} from 'core/ajax';
import * as Templates from 'core/templates';
import {exception as displayError} from 'core/notification';
/**
* The number of colours used to represent the heatmap. (Indexed on 0.)
* @type {number}
*/
const numColours = 2;
/**
* The toggle state of the heatmap.
* @type {boolean}
*/
let toggleState = true;
/**
* Renders the HTML template onto a particular HTML element.
* @param {HTMLElement} element The element to attach the HTML to.
* @param {number} errorCount The number of errors on this module/section.
* @param {number} checkCount The number of checks triggered on this module/section.
* @param {String} displayFormat
* @param {Number} minViews
* @param {Number} viewDelta
* @returns {Promise}
*/
const renderTemplate = (element, errorCount, checkCount, displayFormat, minViews, viewDelta) => {
// Calculate a weight?
const weight = parseInt((errorCount - minViews) / viewDelta * numColours);
const context = {
resultPassed: !errorCount,
classList: '',
passRate: {
errorCount,
checkCount,
failureRate: Math.round(errorCount / checkCount * 100),
},
};
if (!element) {
return Promise.resolve();
}
const elementClassList = ['block_accessreview'];
if (context.resultPassed) {
elementClassList.push('block_accessreview_success');
} else if (weight) {
elementClassList.push('block_accessreview_danger');
} else {
elementClassList.push('block_accessreview_warning');
}
const showIcons = (displayFormat == 'showicons') || (displayFormat == 'showboth');
const showBackground = (displayFormat == 'showbackground') || (displayFormat == 'showboth');
if (showBackground && !showIcons) {
// Only the background is displayed.
// No need to display the template.
// Note: The case where both the background and icons are shown is handled later to avoid jankiness.
element.classList.add(...elementClassList, 'alert');
return Promise.resolve();
}
if (showIcons && !showBackground) {
context.classList = elementClassList.join(' ');
}
// The icons are displayed either with, or without, the background.
return Templates.renderForPromise('block_accessreview/status', context)
.then(({html, js}) => {
Templates.appendNodeContents(element, html, js);
if (showBackground) {
element.classList.add(...elementClassList, 'alert');
}
return;
})
.catch();
};
/**
* Applies the template to all sections and modules on the course page.
*
* @param {Number} courseId
* @param {String} displayFormat
* @param {Boolean} updatePreference
* @returns {Promise}
*/
const showAccessMap = (courseId, displayFormat, updatePreference = false) => {
// Get error data.
return Promise.all(fetchReviewData(courseId, updatePreference))
.then(([sectionData, moduleData]) => {
// Get total data.
const {minViews, viewDelta} = getErrorTotals(sectionData, moduleData);
sectionData.forEach(section => {
const element = document.querySelector(`#section-${section.section} .summary`);
if (!element) {
return;
}
renderTemplate(element, section.numerrors, section.numchecks, displayFormat, minViews, viewDelta);
});
moduleData.forEach(module => {
const element = document.getElementById(`module-${module.cmid}`);
if (!element) {
return;
}
renderTemplate(element, module.numerrors, module.numchecks, displayFormat, minViews, viewDelta);
});
// Change the icon display.
document.querySelector('.icon-accessmap').classList.remove(...['fa-eye-slash']);
document.querySelector('.icon-accessmap').classList.add(...['fa-eye']);
return {
sectionData,
moduleData,
};
})
.catch(displayError);
};
/**
* Hides or removes the templates from the HTML of the current page.
*
* @param {Boolean} updatePreference
*/
const hideAccessMap = (updatePreference = false) => {
// Removes the added elements.
document.querySelectorAll('.block_accessreview_view').forEach(node => node.remove());
const classList = [
'block_accessreview',
'block_accessreview_success',
'block_accessreview_warning',
'block_accessreview_danger',
'block_accessreview_view',
'alert',
];
// Removes the added classes.
document.querySelectorAll('.block_accessreview').forEach(node => node.classList.remove(...classList));
if (updatePreference) {
setToggleStatePreference(false);
}
// Change the icon display.
document.querySelector('.icon-accessmap').classList.remove(...['fa-eye']);
document.querySelector('.icon-accessmap').classList.add(...['fa-eye-slash']);
};
/**
* Toggles the heatmap on/off.
*
* @param {Number} courseId
* @param {String} displayFormat
*/
const toggleAccessMap = (courseId, displayFormat) => {
toggleState = !toggleState;
if (!toggleState) {
hideAccessMap(true);
} else {
showAccessMap(courseId, displayFormat, true);
}
};
/**
* Parses information on the errors, generating the min, max and totals.
*
* @param {Object[]} sectionData The error data for course sections.
* @param {Object[]} moduleData The error data for course modules.
* @returns {Object} An object representing the extra error information.
*/
const getErrorTotals = (sectionData, moduleData) => {
const totals = {
totalErrors: 0,
totalUsers: 0,
minViews: 0,
maxViews: 0,
viewDelta: 0,
};
[].concat(sectionData, moduleData).forEach(item => {
totals.totalErrors += item.numerrors;
if (item.numerrors < totals.minViews) {
totals.minViews = item.numerrors;
}
if (item.numerrors > totals.maxViews) {
totals.maxViews = item.numerrors;
}
totals.totalUsers += item.numchecks;
});
totals.viewDelta = totals.maxViews - totals.minViews + 1;
return totals;
};
const registerEventListeners = (courseId, displayFormat) => {
document.addEventListener('click', e => {
if (e.target.closest('#toggle-accessmap')) {
e.preventDefault();
toggleAccessMap(courseId, displayFormat);
}
});
};
/**
* Set the user preference for the toggle value.
*
* @param {Boolean} toggleState
* @returns {Promise}
*/
const getTogglePreferenceParams = toggleState => {
return {
methodname: 'core_user_update_user_preferences',
args: {
preferences: [{
type: 'block_accessreviewtogglestate',
value: toggleState,
}],
}
};
};
const setToggleStatePreference = toggleState => fetchMany([getTogglePreferenceParams(toggleState)]);
/**
* Fetch the review data.
*
* @param {Number} courseid
* @param {Boolean} updatePreference
* @returns {Promise[]}
*/
const fetchReviewData = (courseid, updatePreference = false) => {
const calls = [
{
methodname: 'block_accessreview_get_section_data',
args: {courseid}
},
{
methodname: 'block_accessreview_get_module_data',
args: {courseid}
},
];
if (updatePreference) {
calls.push(getTogglePreferenceParams(true));
}
return fetchMany(calls);
};
/**
* Setting up the access review module.
* @param {number} toggled A number represnting the state of the review toggle.
* @param {string} displayFormat A string representing the display format for icons.
* @param {number} courseId The course ID.
*/
export const init = (toggled, displayFormat, courseId) => {
// Settings consts.
toggleState = toggled == 1;
if (toggleState) {
showAccessMap(courseId, displayFormat);
}
registerEventListeners(courseId, displayFormat);
};