From 630cde19f11fef84960770d558ef52c619116986 Mon Sep 17 00:00:00 2001 From: Nathan Nguyen Date: Thu, 28 Nov 2024 12:33:59 +1100 Subject: [PATCH] Fix ci errors for javascript --- amd/build/calendar.min.js | 1 - amd/build/calendar.min.js.map | 2 +- amd/build/chart_data.min.js | 1 - amd/build/chart_data.min.js.map | 2 +- amd/build/chart_output_chartjs.min.js | 1 - amd/build/chart_output_chartjs.min.js.map | 2 +- amd/build/dashboard_assessment.min.js | 1 - amd/build/dashboard_assessment.min.js.map | 2 +- amd/build/dashboard_quiz.min.js | 1 - amd/build/dashboard_quiz.min.js.map | 2 +- amd/build/dashboard_quiz_inprogress.min.js | 1 - .../dashboard_quiz_inprogress.min.js.map | 2 +- amd/build/dayview.min.js | 1 - amd/build/dayview.min.js.map | 2 +- amd/build/debouncer.min.js.map | 2 +- amd/build/form_modal.min.js | 3 +- amd/build/form_modal.min.js.map | 2 +- amd/build/modal_large.min.js | 1 - amd/build/modal_large.min.js.map | 2 +- amd/build/override_modal.min.js | 3 +- amd/build/override_modal.min.js.map | 2 +- amd/build/student_search.min.js | 1 - amd/build/student_search.min.js.map | 2 +- amd/build/summary_participants.min.js | 1 - amd/build/summary_participants.min.js.map | 2 +- amd/build/table_handler.min.js | 1 - amd/build/table_handler.min.js.map | 2 +- amd/build/user_preferences.min.js | 1 - amd/build/user_preferences.min.js.map | 2 +- amd/build/zoom_modal.min.js | 3 +- amd/build/zoom_modal.min.js.map | 2 +- amd/src/calendar.js | 28 +++++++++++-------- amd/src/chart_data.js | 1 - amd/src/chart_output_chartjs.js | 7 +++-- amd/src/dashboard_assessment.js | 1 - amd/src/dashboard_quiz.js | 1 - amd/src/dashboard_quiz_inprogress.js | 1 - amd/src/dayview.js | 4 +-- amd/src/debouncer.js | 1 - amd/src/form_modal.js | 9 ++++-- amd/src/modal_large.js | 1 - amd/src/override_modal.js | 18 ++++++++---- amd/src/student_search.js | 1 - amd/src/summary_participants.js | 1 - amd/src/table_handler.js | 3 +- amd/src/user_preferences.js | 1 - amd/src/zoom_modal.js | 9 ++++-- 47 files changed, 71 insertions(+), 69 deletions(-) diff --git a/amd/build/calendar.min.js b/amd/build/calendar.min.js index d3f4fc28..59f5f57f 100644 --- a/amd/build/calendar.min.js +++ b/amd/build/calendar.min.js @@ -1,7 +1,6 @@ /** * Javascript for heatmap calendar generation and display. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/build/calendar.min.js.map b/amd/build/calendar.min.js.map index bc981013..067b1a77 100644 --- a/amd/build/calendar.min.js.map +++ b/amd/build/calendar.min.js.map @@ -1 +1 @@ -{"version":3,"file":"calendar.min.js","sources":["../src/calendar.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\n/**\n * Javascript for heatmap calendar generation and display.\n *\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['core/str', 'core/notification', 'core/ajax'], function (Str, Notification, Ajax) {\n\n /**\n * Module level variables.\n */\n var Calendar = {};\n var eventArray = [];\n const stringArr = [\n {key: 'sun', component: 'calendar'},\n {key: 'mon', component: 'calendar'},\n {key: 'tue', component: 'calendar'},\n {key: 'wed', component: 'calendar'},\n {key: 'thu', component: 'calendar'},\n {key: 'fri', component: 'calendar'},\n {key: 'sat', component: 'calendar'},\n {key: 'jan', component: 'local_assessfreq'},\n {key: 'feb', component: 'local_assessfreq'},\n {key: 'mar', component: 'local_assessfreq'},\n {key: 'apr', component: 'local_assessfreq'},\n {key: 'may', component: 'local_assessfreq'},\n {key: 'jun', component: 'local_assessfreq'},\n {key: 'jul', component: 'local_assessfreq'},\n {key: 'aug', component: 'local_assessfreq'},\n {key: 'sep', component: 'local_assessfreq'},\n {key: 'oct', component: 'local_assessfreq'},\n {key: 'nov', component: 'local_assessfreq'},\n {key: 'dec', component: 'local_assessfreq'},\n ];\n var stringResult;\n var heatRangeMax;\n var heatRangeMin;\n var colorArray;\n var processModules;\n var heatRangeScale = {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0};\n\n /**\n * Pick a contrasting text color based on the background color.\n *\n * @param {String} A hexcolor value.\n * @return {String} The contrasting color (black or white).\n */\n const getContrast = function (hexcolor) {\n\n if (typeof (hexcolor) === \"undefined\") {\n return '#000000';\n }\n\n // If a leading # is provided, remove it.\n if (hexcolor.slice(0, 1) === '#') {\n hexcolor = hexcolor.slice(1);\n }\n\n // Convert to RGB value.\n var r = parseInt(hexcolor.substr(0,2),16);\n var g = parseInt(hexcolor.substr(2,2),16);\n var b = parseInt(hexcolor.substr(4,2),16);\n\n // Get YIQ ratio.\n var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;\n\n // Check contrast.\n return (yiq >= 128) ? '#000000' : '#FFFFFF';\n };\n\n /**\n * Check how many days in a month code.\n * from https://dzone.com/articles/determining-number-days-month.\n *\n * @method daysInMonth\n * @param {Number} month The month to get the number of days for.\n * @param {Number} year The year to get the number of days for.\n */\n const daysInMonth = function (month, year) {\n return 32 - new Date(year, month, 32).getDate();\n };\n\n /**\n * Get the heat colors to use in the heat map via Ajax.\n *\n * @method getHeatColors\n */\n const getHeatColors = function () {\n return new Promise((resolve, reject) => {\n Ajax.call([{\n methodname: 'local_assessfreq_get_heat_colors',\n args: {},\n }], true, false)[0].done(function (response) {\n colorArray = JSON.parse(response);\n resolve(colorArray);\n }).fail(function () {\n reject(new Error('Failed to get heat colors'));\n });\n });\n };\n\n /**\n * Get the event names that we are processing.\n *\n * @method getProcessEvents\n */\n const getProcessModules = function () {\n return new Promise((resolve, reject) => {\n Ajax.call([{\n methodname: 'local_assessfreq_get_process_modules',\n args: {},\n }], true, false)[0].done(function (response) {\n processModules = JSON.parse(response);\n resolve(processModules);\n }).fail(function () {\n reject(new Error('Failed to get process events'));\n });\n });\n };\n\n /**\n * Calculate the min and max values to use in the heatmap.\n *\n * @method daysInMonth\n * @param {Object} eventArray All the event count for the heatmap.\n * @param {Object} dateObj Date details.\n */\n const calcHeatRange = function (eventArray, dateObj) {\n return new Promise((resolve) => {\n\n // Resolve early if there are no events.\n if (typeof (eventArray) === \"undefined\") {\n heatRangeMax = 0;\n heatRangeMin = 0;\n\n resolve(eventArray);\n }\n // If scheduled tasks have not run yet we may not have any data.\n let eventArrayLength = Object.keys(eventArray).length;\n if ((eventArrayLength > 0) && (eventArray[dateObj.year] !== \"undefined\")) {\n let eventcount = new Array;\n let year = eventArray[dateObj.year];\n\n // Iterate through all the event counts.\n // This code looks nasty but there is only 366 days in a year.\n for (let i = 0; i < 12; i++) {\n if (typeof year[i] !== \"undefined\") {\n let month = year[i];\n for (let j = 0; j < 32; j++) {\n if (typeof month[j] !== \"undefined\") {\n eventcount.push(month[j].number);\n }\n }\n }\n }\n\n // Get min and max values to calculate heat spread.\n heatRangeMax = Math.max(...eventcount);\n heatRangeMin = Math.min(...eventcount);\n } else {\n heatRangeMax = 0;\n heatRangeMin = 0;\n }\n\n resolve(eventArray);\n });\n };\n\n /**\n * Translate assessment frequency to a heat value.\n *\n * @method getHeat\n * @param {Number} eventCount The count to get the heat value.\n * @return {Number} heat The heat value.\n */\n const getHeat = function (eventCount) {\n let scaleMin = 1;\n\n if (eventCount == heatRangeMin) {\n return scaleMin;\n }\n\n const scaleRange = 5; // 0 - 5 steps.\n const localRange = heatRangeMax - heatRangeMin;\n const localPercent = (eventCount - heatRangeMin) / localRange;\n let heat = Math.round((localPercent * scaleRange) + 1);\n\n // Clamp values.\n if (heat < 1) {\n heat = 1;\n }\n\n if (heat > 6) {\n heat = 6;\n }\n\n return heat;\n };\n\n /**\n * Get the events to display in the calendar via ajax call.\n *\n * @method getEvents\n * @param {Number} year The year to get the events for.\n * @param {String} metric The type of metric to get, 'students' or 'assess'.\n * @param {Array} modules Array of the modules to get.\n * @return {Promise}\n */\n const getEvents = function ({year, metric, modules}) {\n return new Promise((resolve, reject) => {\n let args = {\n year: year,\n metric: metric,\n modules: modules\n };\n let jsonArgs = JSON.stringify(args);\n\n // Get the events to use in the mapping.\n Ajax.call([{\n methodname: 'local_assessfreq_get_frequency',\n args: {\n jsondata: jsonArgs\n },\n }])[0].done((response) => {\n eventArray = JSON.parse(response);\n resolve(eventArray);\n }).fail(() => {\n reject(new Error('Failed to get events'));\n });\n });\n };\n\n /**\n * Get the events for a particular month and year.\n *\n * @param {Number} year The year to get the number of days for.\n * @param {Number} month The month to get the number of days for.\n * @return {Array} monthevents The events for the supplied month.\n */\n const getMonthEvents = function (year, month) {\n let monthevents;\n\n if ((typeof eventArray[year] !== \"undefined\") && (typeof eventArray[year][month] !== \"undefined\")) {\n monthevents = eventArray[year][month];\n }\n\n return monthevents;\n };\n\n /**\n * Create the table structure for the calendar months.\n *\n * @oaram {Number} year The year to generate the tables for.\n * @param {Number} startMonth The month to start table generation from.\n * @param {Number} endMonth The month to generate the tables to.\n * @return {Promise}\n */\n const createTables = function ({year, startMonth, endMonth}) {\n return new Promise((resolve, reject) => {\n let calendarContainer = document.createElement('div');\n let month = startMonth;\n\n // Itterate through and build are tables.\n for (let i = startMonth; i <= endMonth; i++) {\n // Setup some elements.\n let container = document.createElement('div');\n container.classList.add('local-assessfreq-month');\n let table = document.createElement('table');\n table.classList.add('table-striped');\n let thead = document.createElement('thead');\n let tbody = document.createElement('tbody');\n tbody.id = 'calendar-body-' + i;\n let monthRow = document.createElement('tr');\n let dayrow = document.createElement('tr');\n let monthHeader = document.createElement('th');\n monthHeader.colSpan = 7;\n monthHeader.innerHTML = stringResult[(7 + month)];\n\n for (let j = 0; j < 7; j++) {\n let dayHeader = document.createElement('th');\n dayHeader.innerHTML = stringResult[j];\n dayrow.appendChild(dayHeader);\n }\n\n // Construct the table.\n monthRow.appendChild(monthHeader);\n\n thead.appendChild(monthRow);\n thead.appendChild(dayrow);\n\n table.appendChild(thead);\n table.appendChild(tbody);\n\n container.appendChild(table);\n\n // Add to parent.\n calendarContainer.appendChild(container);\n\n // Increment variables.\n month++;\n }\n\n if ((typeof year === 'undefined') || (typeof startMonth === 'undefined') || (typeof endMonth === 'undefined')) {\n reject(Error('Failed to create calendar tables.'));\n } else {\n const resultObj = {\n calendarContainer : calendarContainer,\n year : year,\n startMonth : startMonth\n };\n resolve(resultObj);\n }\n });\n };\n\n /**\n * Generate the tooltip HTML.\n *\n * @param {Object} dayArray The details of the events for that day/\n * @return {String} tipHTML The HTML for the tooltip.\n */\n const getTooltip = function (dayArray) {\n let tipHTML = '';\n\n for (let [key, value] of Object.entries(dayArray)) {\n tipHTML += '' + processModules[key] + ': ' + value + '
';\n }\n\n return tipHTML;\n };\n\n /**\n * Generate calendar markup for the month.\n *\n * @param {Object} table The base table to populate.\n * @param {Number} year The year to generate calendar for.\n * @param {Number} month The monthe to generate calendar for.\n */\n const populateCalendarDays = function (table, year, month) {\n let firstDay = (new Date(year, month)).getDay(); // Get the starting day of the month.\n let monthEvents = getMonthEvents(year, (month + 1)); // We add one due to month diferences between PHP and JS.\n let date = 1; // Creating all cells.\n\n for (let i = 0; i < 6; i++) {\n let row = document.createElement(\"tr\"); // Creates a table row.\n\n // Creating individual cells, filing them up with data.\n for (let j = 0; j < 7; j++) {\n if (i === 0 && j < firstDay) {\n var cell = document.createElement(\"td\");\n var cellText = document.createTextNode(\"\");\n cell.dataset.event = 'false';\n } else if (date > daysInMonth(month, year)) { // Break if we have generated all the days for this month.\n break;\n } else {\n cell = document.createElement(\"td\");\n cellText = document.createTextNode(date);\n if ((typeof monthEvents !== \"undefined\") && (monthEvents.hasOwnProperty(date))) {\n let heat = getHeat(monthEvents[date]['number']);\n\n if (heatRangeScale[heat] == 0 || heatRangeScale[heat] > monthEvents[date]['number']) {\n heatRangeScale[heat] = monthEvents[date]['number'];\n }\n\n cell.style.backgroundColor = colorArray[heat];\n cell.style.color = getContrast(colorArray[heat]);\n\n // Add tooltip to cell.\n cell.dataset.toggle = 'tooltip';\n cell.dataset.html = 'true';\n cell.dataset.event = 'true';\n cell.dataset.date = year + '-' + (month + 1) + '-' + date;\n cell.title = getTooltip(monthEvents[date]);\n cell.style.cursor = \"pointer\";\n }\n date++;\n }\n\n cell.appendChild(cellText);\n row.appendChild(cell);\n }\n table.appendChild(row); // Appending each row into calendar body.\n }\n };\n\n /**\n * Controls the population of the calendar in to the base tables.\n *\n * @param {Object} calendarContainer the container to populate.\n * @param {Number} year The year to generate calendar for.\n * @param {Number} startMonth The month to start generation from.\n * @return {Promise}\n */\n const populateCalendar = function ({calendarContainer, year, startMonth}) {\n return new Promise((resolve, reject) => {\n // Get the table boodies.\n let tables = calendarContainer.getElementsByTagName(\"tbody\");\n let month = startMonth;\n\n // For each table body populate with calendar.\n for (var i = 0; i < tables.length; i++) {\n let table = tables[i];\n populateCalendarDays(table, year, month);\n month++;\n }\n\n if (typeof calendarContainer === 'undefined') {\n reject(Error('Failed to populate calendar tables.'));\n } else {\n resolve(calendarContainer);\n }\n });\n };\n\n /**\n * Create the heatmap scale for the calendar.\n *\n * @method createHeatScale\n */\n Calendar.createHeatScale = function () {\n return new Promise((resolve) => {\n let table = document.createElement('table');\n let tbody = document.createElement('tbody');\n let trow = document.createElement('tr');\n\n for (var i = 1; i < 7; i++) {\n if (heatRangeScale[i] !== 0) {\n let cell = document.createElement('td');\n let cellText = document.createTextNode(heatRangeScale[i] + '+');\n\n cell.appendChild(cellText);\n cell.style.backgroundColor = colorArray[i];\n cell.style.color = getContrast(colorArray[i]);\n\n trow.appendChild(cell);\n }\n }\n\n tbody.appendChild(trow);\n table.appendChild(tbody);\n\n // Reset heat range scale.\n heatRangeScale = {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0};\n\n resolve(table);\n });\n };\n\n /**\n * Initialise method for report calendar heatmap creation.\n *\n * @param {Number} year The year to generate the heatmap for.\n * @param {Number} startMonth The month to start with for the heatmap calendar.\n * @param {Number} endMonth The month to end with for the heatmap calendar.\n * @param {String} metric The type of metric to display, 'students' or 'aseess'.\n * @param {Array} modules The modules to display in the heatamp.\n * @return {Promise}\n */\n Calendar.generate = function (year, startMonth, endMonth, metric, modules) {\n return new Promise((resolve, reject) => {\n const dateObj = {\n year : year,\n startMonth : startMonth,\n endMonth : endMonth\n };\n\n const eventObj = {\n year : year,\n metric : metric,\n modules : modules\n };\n\n Str.get_strings(stringArr).catch(() => { // Get required strings.\n Notification.exception(new Error('Failed to load strings'));\n return;\n }).then(stringReturn => { // Save string to global to be used later.\n stringResult = stringReturn;\n return eventObj;\n })\n .then(getEvents)\n .then((eventArray) => {\n calcHeatRange(eventArray, dateObj);\n })\n .then(getHeatColors)\n .then(getProcessModules)\n .then(() => {\n return dateObj;\n })\n .then(createTables) // Create tables for calendar.\n .then(populateCalendar)\n .then((calendarHTML) => { // Return the result of the generate function.\n if (typeof calendarHTML !== 'undefined') {\n resolve(calendarHTML);\n } else {\n reject(Error('Could not generate calendar'));\n }\n });\n });\n\n };\n\n return Calendar;\n});\n"],"names":["define","Str","Notification","Ajax","Calendar","eventArray","stringArr","key","component","stringResult","heatRangeMax","heatRangeMin","colorArray","processModules","heatRangeScale","getContrast","hexcolor","slice","parseInt","substr","daysInMonth","month","year","Date","getDate","getHeatColors","Promise","resolve","reject","call","methodname","args","done","response","JSON","parse","fail","Error","getProcessModules","getHeat","eventCount","localPercent","heat","Math","round","getEvents","metric","modules","jsonArgs","stringify","jsondata","createTables","startMonth","endMonth","calendarContainer","document","createElement","i","container","classList","add","table","thead","tbody","id","monthRow","dayrow","monthHeader","colSpan","innerHTML","j","dayHeader","appendChild","getTooltip","dayArray","tipHTML","value","Object","entries","populateCalendarDays","firstDay","getDay","monthEvents","monthevents","getMonthEvents","date","row","cell","cellText","createTextNode","dataset","event","hasOwnProperty","style","backgroundColor","color","toggle","html","title","cursor","populateCalendar","tables","getElementsByTagName","length","createHeatScale","trow","generate","dateObj","eventObj","get_strings","catch","exception","then","stringReturn","keys","eventcount","Array","push","number","max","min","calcHeatRange","calendarHTML"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"calendar.min.js","sources":["../src/calendar.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\n/**\n * Javascript for heatmap calendar generation and display.\n *\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['core/str', 'core/notification', 'core/ajax'], function (Str, Notification, Ajax) {\n\n /**\n * Module level variables.\n */\n var Calendar = {};\n var eventArray = [];\n const stringArr = [\n {key: 'sun', component: 'calendar'},\n {key: 'mon', component: 'calendar'},\n {key: 'tue', component: 'calendar'},\n {key: 'wed', component: 'calendar'},\n {key: 'thu', component: 'calendar'},\n {key: 'fri', component: 'calendar'},\n {key: 'sat', component: 'calendar'},\n {key: 'jan', component: 'local_assessfreq'},\n {key: 'feb', component: 'local_assessfreq'},\n {key: 'mar', component: 'local_assessfreq'},\n {key: 'apr', component: 'local_assessfreq'},\n {key: 'may', component: 'local_assessfreq'},\n {key: 'jun', component: 'local_assessfreq'},\n {key: 'jul', component: 'local_assessfreq'},\n {key: 'aug', component: 'local_assessfreq'},\n {key: 'sep', component: 'local_assessfreq'},\n {key: 'oct', component: 'local_assessfreq'},\n {key: 'nov', component: 'local_assessfreq'},\n {key: 'dec', component: 'local_assessfreq'},\n ];\n var stringResult;\n var heatRangeMax;\n var heatRangeMin;\n var colorArray;\n var processModules;\n var heatRangeScale = {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0};\n\n /**\n * Pick a contrasting text color based on the background color.\n *\n * @param {String} hexcolor A hexcolor value.\n * @return {String} The contrasting color (black or white).\n */\n const getContrast = function (hexcolor) {\n\n if (typeof (hexcolor) === \"undefined\") {\n return '#000000';\n }\n\n // If a leading # is provided, remove it.\n if (hexcolor.slice(0, 1) === '#') {\n hexcolor = hexcolor.slice(1);\n }\n\n // Convert to RGB value.\n var r = parseInt(hexcolor.substr(0,2),16);\n var g = parseInt(hexcolor.substr(2,2),16);\n var b = parseInt(hexcolor.substr(4,2),16);\n\n // Get YIQ ratio.\n var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;\n\n // Check contrast.\n return (yiq >= 128) ? '#000000' : '#FFFFFF';\n };\n\n /**\n * Check how many days in a month code.\n * from https://dzone.com/articles/determining-number-days-month.\n *\n * @method daysInMonth\n * @param {Number} month The month to get the number of days for.\n * @param {Number} year The year to get the number of days for.\n */\n const daysInMonth = function (month, year) {\n return 32 - new Date(year, month, 32).getDate();\n };\n\n /**\n * Get the heat colors to use in the heat map via Ajax.\n *\n * @method getHeatColors\n */\n const getHeatColors = function () {\n return new Promise((resolve, reject) => {\n Ajax.call([{\n methodname: 'local_assessfreq_get_heat_colors',\n args: {},\n }], true, false)[0].done(function (response) {\n colorArray = JSON.parse(response);\n resolve(colorArray);\n }).fail(function () {\n reject(new Error('Failed to get heat colors'));\n });\n });\n };\n\n /**\n * Get the event names that we are processing.\n *\n * @method getProcessEvents\n */\n const getProcessModules = function () {\n return new Promise((resolve, reject) => {\n Ajax.call([{\n methodname: 'local_assessfreq_get_process_modules',\n args: {},\n }], true, false)[0].done(function (response) {\n processModules = JSON.parse(response);\n resolve(processModules);\n }).fail(function () {\n reject(new Error('Failed to get process events'));\n });\n });\n };\n\n /**\n * Calculate the min and max values to use in the heatmap.\n *\n * @method daysInMonth\n * @param {Object} eventArray All the event count for the heatmap.\n * @param {Object} dateObj Date details.\n */\n const calcHeatRange = function (eventArray, dateObj) {\n return new Promise((resolve) => {\n\n // Resolve early if there are no events.\n if (typeof (eventArray) === \"undefined\") {\n heatRangeMax = 0;\n heatRangeMin = 0;\n\n resolve(eventArray);\n }\n // If scheduled tasks have not run yet we may not have any data.\n let eventArrayLength = Object.keys(eventArray).length;\n if ((eventArrayLength > 0) && (eventArray[dateObj.year] !== \"undefined\")) {\n let eventcount = new Array;\n let year = eventArray[dateObj.year];\n\n // Iterate through all the event counts.\n // This code looks nasty but there is only 366 days in a year.\n for (let i = 0; i < 12; i++) {\n if (typeof year[i] !== \"undefined\") {\n let month = year[i];\n for (let j = 0; j < 32; j++) {\n if (typeof month[j] !== \"undefined\") {\n eventcount.push(month[j].number);\n }\n }\n }\n }\n\n // Get min and max values to calculate heat spread.\n heatRangeMax = Math.max(...eventcount);\n heatRangeMin = Math.min(...eventcount);\n } else {\n heatRangeMax = 0;\n heatRangeMin = 0;\n }\n\n resolve(eventArray);\n });\n };\n\n /**\n * Translate assessment frequency to a heat value.\n *\n * @method getHeat\n * @param {Number} eventCount The count to get the heat value.\n * @return {Number} heat The heat value.\n */\n const getHeat = function (eventCount) {\n let scaleMin = 1;\n\n if (eventCount == heatRangeMin) {\n return scaleMin;\n }\n\n const scaleRange = 5; // 0 - 5 steps.\n const localRange = heatRangeMax - heatRangeMin;\n const localPercent = (eventCount - heatRangeMin) / localRange;\n let heat = Math.round((localPercent * scaleRange) + 1);\n\n // Clamp values.\n if (heat < 1) {\n heat = 1;\n }\n\n if (heat > 6) {\n heat = 6;\n }\n\n return heat;\n };\n\n /**\n * Get the events to display in the calendar via ajax call.\n *\n * @method getEvents\n *\n * @param {Object} args The arguments to pass to the ajax call.\n * @param {Number} args.year The year to get the events for.\n * @param {String} args.metric The metric to get the events for.\n * @param {Array} args.modules The modules to get the events for.\n *\n * @return {Promise}\n */\n const getEvents = function ({year, metric, modules}) {\n return new Promise((resolve, reject) => {\n let args = {\n year: year,\n metric: metric,\n modules: modules\n };\n let jsonArgs = JSON.stringify(args);\n\n // Get the events to use in the mapping.\n Ajax.call([{\n methodname: 'local_assessfreq_get_frequency',\n args: {\n jsondata: jsonArgs\n },\n }])[0].done((response) => {\n eventArray = JSON.parse(response);\n resolve(eventArray);\n }).fail(() => {\n reject(new Error('Failed to get events'));\n });\n });\n };\n\n /**\n * Get the events for a particular month and year.\n *\n * @param {Number} year The year to get the number of days for.\n * @param {Number} month The month to get the number of days for.\n * @return {Array} monthevents The events for the supplied month.\n */\n const getMonthEvents = function (year, month) {\n let monthevents;\n\n if ((typeof eventArray[year] !== \"undefined\") && (typeof eventArray[year][month] !== \"undefined\")) {\n monthevents = eventArray[year][month];\n }\n\n return monthevents;\n };\n\n /**\n * Create the table structure for the calendar months.\n *\n * @param {Object} args The arguments to pass to the ajax call.\n * @param {Number} args.year The year to get the events for.\n * @param {Number} args.startMonth The month to start the calendar\n * @param {Number} args.endMonth The month to end the calendar\n *\n * @return {Promise}\n */\n const createTables = function ({year, startMonth, endMonth}) {\n return new Promise((resolve, reject) => {\n let calendarContainer = document.createElement('div');\n let month = startMonth;\n\n // Itterate through and build are tables.\n for (let i = startMonth; i <= endMonth; i++) {\n // Setup some elements.\n let container = document.createElement('div');\n container.classList.add('local-assessfreq-month');\n let table = document.createElement('table');\n table.classList.add('table-striped');\n let thead = document.createElement('thead');\n let tbody = document.createElement('tbody');\n tbody.id = 'calendar-body-' + i;\n let monthRow = document.createElement('tr');\n let dayrow = document.createElement('tr');\n let monthHeader = document.createElement('th');\n monthHeader.colSpan = 7;\n monthHeader.innerHTML = stringResult[(7 + month)];\n\n for (let j = 0; j < 7; j++) {\n let dayHeader = document.createElement('th');\n dayHeader.innerHTML = stringResult[j];\n dayrow.appendChild(dayHeader);\n }\n\n // Construct the table.\n monthRow.appendChild(monthHeader);\n\n thead.appendChild(monthRow);\n thead.appendChild(dayrow);\n\n table.appendChild(thead);\n table.appendChild(tbody);\n\n container.appendChild(table);\n\n // Add to parent.\n calendarContainer.appendChild(container);\n\n // Increment variables.\n month++;\n }\n\n if ((typeof year === 'undefined') || (typeof startMonth === 'undefined') || (typeof endMonth === 'undefined')) {\n reject(Error('Failed to create calendar tables.'));\n } else {\n const resultObj = {\n calendarContainer : calendarContainer,\n year : year,\n startMonth : startMonth\n };\n resolve(resultObj);\n }\n });\n };\n\n /**\n * Generate the tooltip HTML.\n *\n * @param {Object} dayArray The details of the events for that day/\n * @return {String} tipHTML The HTML for the tooltip.\n */\n const getTooltip = function (dayArray) {\n let tipHTML = '';\n\n for (let [key, value] of Object.entries(dayArray)) {\n tipHTML += '' + processModules[key] + ': ' + value + '
';\n }\n\n return tipHTML;\n };\n\n /**\n * Generate calendar markup for the month.\n *\n * @param {Object} table The base table to populate.\n * @param {Number} year The year to generate calendar for.\n * @param {Number} month The monthe to generate calendar for.\n */\n const populateCalendarDays = function (table, year, month) {\n let firstDay = (new Date(year, month)).getDay(); // Get the starting day of the month.\n let monthEvents = getMonthEvents(year, (month + 1)); // We add one due to month diferences between PHP and JS.\n let date = 1; // Creating all cells.\n\n for (let i = 0; i < 6; i++) {\n let row = document.createElement(\"tr\"); // Creates a table row.\n\n // Creating individual cells, filing them up with data.\n for (let j = 0; j < 7; j++) {\n if (i === 0 && j < firstDay) {\n var cell = document.createElement(\"td\");\n var cellText = document.createTextNode(\"\");\n cell.dataset.event = 'false';\n } else if (date > daysInMonth(month, year)) { // Break if we have generated all the days for this month.\n break;\n } else {\n cell = document.createElement(\"td\");\n cellText = document.createTextNode(date);\n if ((typeof monthEvents !== \"undefined\") && (monthEvents.hasOwnProperty(date))) {\n let heat = getHeat(monthEvents[date]['number']);\n\n if (heatRangeScale[heat] == 0 || heatRangeScale[heat] > monthEvents[date]['number']) {\n heatRangeScale[heat] = monthEvents[date]['number'];\n }\n\n cell.style.backgroundColor = colorArray[heat];\n cell.style.color = getContrast(colorArray[heat]);\n\n // Add tooltip to cell.\n cell.dataset.toggle = 'tooltip';\n cell.dataset.html = 'true';\n cell.dataset.event = 'true';\n cell.dataset.date = year + '-' + (month + 1) + '-' + date;\n cell.title = getTooltip(monthEvents[date]);\n cell.style.cursor = \"pointer\";\n }\n date++;\n }\n\n cell.appendChild(cellText);\n row.appendChild(cell);\n }\n table.appendChild(row); // Appending each row into calendar body.\n }\n };\n\n /**\n * Controls the population of the calendar in to the base tables.\n *\n * @param {Object} args The arguments to pass to the ajax call.\n * @param {Object} args.calendarContainer The container to populate the calendar into.\n * @param {Number} args.year The year to get the events for.\n * @param {Number} args.startMonth The month to start the calendar\n *\n * @return {Promise}\n */\n const populateCalendar = function ({calendarContainer, year, startMonth}) {\n return new Promise((resolve, reject) => {\n // Get the table boodies.\n let tables = calendarContainer.getElementsByTagName(\"tbody\");\n let month = startMonth;\n\n // For each table body populate with calendar.\n for (var i = 0; i < tables.length; i++) {\n let table = tables[i];\n populateCalendarDays(table, year, month);\n month++;\n }\n\n if (typeof calendarContainer === 'undefined') {\n reject(Error('Failed to populate calendar tables.'));\n } else {\n resolve(calendarContainer);\n }\n });\n };\n\n /**\n * Create the heatmap scale for the calendar.\n *\n * @method createHeatScale\n */\n Calendar.createHeatScale = function () {\n return new Promise((resolve) => {\n let table = document.createElement('table');\n let tbody = document.createElement('tbody');\n let trow = document.createElement('tr');\n\n for (var i = 1; i < 7; i++) {\n if (heatRangeScale[i] !== 0) {\n let cell = document.createElement('td');\n let cellText = document.createTextNode(heatRangeScale[i] + '+');\n\n cell.appendChild(cellText);\n cell.style.backgroundColor = colorArray[i];\n cell.style.color = getContrast(colorArray[i]);\n\n trow.appendChild(cell);\n }\n }\n\n tbody.appendChild(trow);\n table.appendChild(tbody);\n\n // Reset heat range scale.\n heatRangeScale = {'1': 0, '2': 0, '3': 0, '4': 0, '5': 0, '6': 0};\n\n resolve(table);\n });\n };\n\n /**\n * Initialise method for report calendar heatmap creation.\n *\n * @param {Number} year The year to generate the heatmap for.\n * @param {Number} startMonth The month to start with for the heatmap calendar.\n * @param {Number} endMonth The month to end with for the heatmap calendar.\n * @param {String} metric The type of metric to display, 'students' or 'aseess'.\n * @param {Array} modules The modules to display in the heatamp.\n * @return {Promise}\n */\n Calendar.generate = function (year, startMonth, endMonth, metric, modules) {\n return new Promise((resolve, reject) => {\n const dateObj = {\n year : year,\n startMonth : startMonth,\n endMonth : endMonth\n };\n\n const eventObj = {\n year : year,\n metric : metric,\n modules : modules\n };\n\n Str.get_strings(stringArr).catch(() => { // Get required strings.\n Notification.exception(new Error('Failed to load strings'));\n return;\n }).then(stringReturn => { // Save string to global to be used later.\n stringResult = stringReturn;\n return eventObj;\n })\n .then(getEvents)\n .then((eventArray) => {\n calcHeatRange(eventArray, dateObj);\n })\n .then(getHeatColors)\n .then(getProcessModules)\n .then(() => {\n return dateObj;\n })\n .then(createTables) // Create tables for calendar.\n .then(populateCalendar)\n .then((calendarHTML) => { // Return the result of the generate function.\n if (typeof calendarHTML !== 'undefined') {\n resolve(calendarHTML);\n } else {\n reject(Error('Could not generate calendar'));\n }\n });\n });\n\n };\n\n return Calendar;\n});\n"],"names":["define","Str","Notification","Ajax","Calendar","eventArray","stringArr","key","component","stringResult","heatRangeMax","heatRangeMin","colorArray","processModules","heatRangeScale","getContrast","hexcolor","slice","parseInt","substr","daysInMonth","month","year","Date","getDate","getHeatColors","Promise","resolve","reject","call","methodname","args","done","response","JSON","parse","fail","Error","getProcessModules","getHeat","eventCount","localPercent","heat","Math","round","getEvents","metric","modules","jsonArgs","stringify","jsondata","createTables","startMonth","endMonth","calendarContainer","document","createElement","i","container","classList","add","table","thead","tbody","id","monthRow","dayrow","monthHeader","colSpan","innerHTML","j","dayHeader","appendChild","getTooltip","dayArray","tipHTML","value","Object","entries","populateCalendarDays","firstDay","getDay","monthEvents","monthevents","getMonthEvents","date","row","cell","cellText","createTextNode","dataset","event","hasOwnProperty","style","backgroundColor","color","toggle","html","title","cursor","populateCalendar","tables","getElementsByTagName","length","createHeatScale","trow","generate","dateObj","eventObj","get_strings","catch","exception","then","stringReturn","keys","eventcount","Array","push","number","max","min","calcHeatRange","calendarHTML"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/chart_data.min.js b/amd/build/chart_data.min.js index 10670f79..19594e64 100644 --- a/amd/build/chart_data.min.js +++ b/amd/build/chart_data.min.js @@ -3,7 +3,6 @@ define("local_assessfreq/chart_data",["exports","core/fragment","core/notificati * Chart data JS module. * * @module local_assessfreq/char_data - * @package local_assessfreq * @copyright 2020 Guillermo Gomez * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */let cards,contextId,fragment,template;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=_exports.getCardCharts=void 0,_fragment=_interopRequireDefault(_fragment),_notification=_interopRequireDefault(_notification),Str=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}(Str),_templates=_interopRequireDefault(_templates);_exports.getCardCharts=(quizId,hoursFilter,yearSelect)=>{cards.forEach((cardData=>{let cardElement=document.getElementById(cardData.cardId),spinner=cardElement.getElementsByClassName("overlay-icon-container")[0],chartBody=cardElement.getElementsByClassName("chart-body")[0],values={call:cardData.call};hoursFilter&&(values.hoursahead=hoursFilter[0],values.hoursbehind=hoursFilter[1]),quizId&&(values.quiz=quizId),yearSelect&&(values.year=yearSelect);let params={data:JSON.stringify(values)};spinner.classList.remove("hide"),_fragment.default.loadFragment("local_assessfreq",fragment,contextId,params).done((response=>{let resObj=JSON.parse(response);if(!0===resObj.hasdata){let context={withtable:!0,chartdata:JSON.stringify(resObj.chart)};return void 0!==cardData.aspect&&(context.aspect=cardData.aspect),void _templates.default.render(template,context).done(((html,js)=>{spinner.classList.add("hide"),_templates.default.replaceNodeContents(chartBody,html,js)})).fail((()=>{_notification.default.exception(new Error("Failed to load chart template."))}))}Str.get_string("nodata","local_assessfreq").then((str=>{const noDatastr=document.createElement("h3");noDatastr.innerHTML=str,chartBody.innerHTML=noDatastr.outerHTML,spinner.classList.add("hide")})).catch((()=>{_notification.default.exception(new Error("Failed to load string: nodata"))}))})).fail((()=>{_notification.default.exception(new Error("Failed to load card."))}))}))};_exports.init=(cardsArray,contextIdChart,fragmentChart,templateChart)=>{cards=cardsArray,contextId=contextIdChart,fragment=fragmentChart,template=templateChart}})); diff --git a/amd/build/chart_data.min.js.map b/amd/build/chart_data.min.js.map index 4e926aeb..2dbb84b3 100644 --- a/amd/build/chart_data.min.js.map +++ b/amd/build/chart_data.min.js.map @@ -1 +1 @@ -{"version":3,"file":"chart_data.min.js","sources":["../src/chart_data.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\n/**\n * Chart data JS module.\n *\n * @module local_assessfreq/char_data\n * @package local_assessfreq\n * @copyright 2020 Guillermo Gomez \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Fragment from 'core/fragment';\nimport Notification from 'core/notification';\nimport * as Str from 'core/str';\nimport Templates from 'core/templates';\n\n/**\n * Module level variables.\n */\nlet cards;\nlet contextId;\nlet fragment;\nlet template;\n\n/**\n * For each of the cards on the dashboard get their corresponding chart data.\n * Data is based on the year variable from the corresponding dropdown.\n * Chart data is loaded via ajax.\n *\n * @param {int|null} quizId The quiz Id.\n * @param {array|null} hoursFilter Array with hour ahead or behind preference.\n * @param {int|null} yearSelect Year selected.\n */\nexport const getCardCharts = (quizId, hoursFilter, yearSelect) => {\n cards.forEach((cardData) => {\n let cardElement = document.getElementById(cardData.cardId);\n let spinner = cardElement.getElementsByClassName('overlay-icon-container')[0];\n let chartBody = cardElement.getElementsByClassName('chart-body')[0];\n let values = {'call': cardData.call};\n // Add values to Object depending on dashboard type.\n if (hoursFilter) {\n values.hoursahead = hoursFilter[0];\n values.hoursbehind = hoursFilter[1];\n }\n if (quizId) {\n values.quiz = quizId;\n }\n if (yearSelect) {\n values.year = yearSelect;\n }\n let params = {'data': JSON.stringify(values)};\n\n spinner.classList.remove('hide'); // Show sinner if not already shown.\n Fragment.loadFragment('local_assessfreq', fragment, contextId, params)\n .done((response) => {\n let resObj = JSON.parse(response);\n if (resObj.hasdata === true) {\n let context = {\n 'withtable': true, 'chartdata': JSON.stringify(resObj.chart)\n };\n if (typeof cardData.aspect !== 'undefined') {\n context.aspect = cardData.aspect;\n }\n Templates.render(template, context).done((html, js) => {\n spinner.classList.add('hide'); // Hide spinner if not already hidden.\n // Load card body.\n Templates.replaceNodeContents(chartBody, html, js);\n }).fail(() => {\n Notification.exception(new Error('Failed to load chart template.'));\n return;\n });\n return;\n } else {\n Str.get_string('nodata', 'local_assessfreq').then((str) => {\n const noDatastr = document.createElement('h3');\n noDatastr.innerHTML = str;\n chartBody.innerHTML = noDatastr.outerHTML;\n spinner.classList.add('hide'); // Hide spinner if not already hidden.\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: nodata'));\n });\n }\n }).fail(() => {\n Notification.exception(new Error('Failed to load card.'));\n return;\n });\n });\n};\n\n/**\n * Initialise method for table handler.\n *\n * @param {array} cardsArray Cards array.\n * @param {int} contextIdChart The context id.\n * @param {string} fragmentChart Fragment name.\n * @param {string} templateChart Template name.\n */\nexport const init = (cardsArray, contextIdChart, fragmentChart, templateChart) => {\n cards = cardsArray;\n contextId = contextIdChart;\n fragment = fragmentChart;\n template = templateChart;\n};\n"],"names":["cards","contextId","fragment","template","quizId","hoursFilter","yearSelect","forEach","cardData","cardElement","document","getElementById","cardId","spinner","getElementsByClassName","chartBody","values","call","hoursahead","hoursbehind","quiz","year","params","JSON","stringify","classList","remove","loadFragment","done","response","resObj","parse","hasdata","context","chart","aspect","render","html","js","add","replaceNodeContents","fail","exception","Error","Str","get_string","then","str","noDatastr","createElement","innerHTML","outerHTML","catch","cardsArray","contextIdChart","fragmentChart","templateChart"],"mappings":";;;;;;;;SAgCIA,MACAC,UACAC,SACAC,w6BAWyB,CAACC,OAAQC,YAAaC,cAC/CN,MAAMO,SAASC,eACPC,YAAcC,SAASC,eAAeH,SAASI,QAC/CC,QAAUJ,YAAYK,uBAAuB,0BAA0B,GACvEC,UAAYN,YAAYK,uBAAuB,cAAc,GAC7DE,OAAS,MAASR,SAASS,MAE3BZ,cACAW,OAAOE,WAAab,YAAY,GAChCW,OAAOG,YAAcd,YAAY,IAEjCD,SACAY,OAAOI,KAAOhB,QAEdE,aACAU,OAAOK,KAAOf,gBAEdgB,OAAS,MAASC,KAAKC,UAAUR,SAErCH,QAAQY,UAAUC,OAAO,0BAChBC,aAAa,mBAAoBzB,SAAUD,UAAWqB,QAC1DM,MAAMC,eACCC,OAASP,KAAKQ,MAAMF,cACD,IAAnBC,OAAOE,QAAkB,KACrBC,QAAU,YACG,YAAmBV,KAAKC,UAAUM,OAAOI,oBAE3B,IAApB1B,SAAS2B,SAChBF,QAAQE,OAAS3B,SAAS2B,gCAEpBC,OAAOjC,SAAU8B,SAASL,MAAK,CAACS,KAAMC,MAC5CzB,QAAQY,UAAUc,IAAI,2BAEZC,oBAAoBzB,UAAWsB,KAAMC,OAChDG,MAAK,2BACSC,UAAU,IAAIC,MAAM,sCAKrCC,IAAIC,WAAW,SAAU,oBAAoBC,MAAMC,YACzCC,UAAYtC,SAASuC,cAAc,MACzCD,UAAUE,UAAYH,IACtBhC,UAAUmC,UAAYF,UAAUG,UAChCtC,QAAQY,UAAUc,IAAI,WAEvBa,OAAM,2BACQV,UAAU,IAAIC,MAAM,wCAG1CF,MAAK,2BACSC,UAAU,IAAIC,MAAM,8CAc7B,CAACU,WAAYC,eAAgBC,cAAeC,iBAC5DxD,MAAQqD,WACRpD,UAAYqD,eACZpD,SAAWqD,cACXpD,SAAWqD"} \ No newline at end of file +{"version":3,"file":"chart_data.min.js","sources":["../src/chart_data.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\n/**\n * Chart data JS module.\n *\n * @module local_assessfreq/char_data\n * @copyright 2020 Guillermo Gomez \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Fragment from 'core/fragment';\nimport Notification from 'core/notification';\nimport * as Str from 'core/str';\nimport Templates from 'core/templates';\n\n/**\n * Module level variables.\n */\nlet cards;\nlet contextId;\nlet fragment;\nlet template;\n\n/**\n * For each of the cards on the dashboard get their corresponding chart data.\n * Data is based on the year variable from the corresponding dropdown.\n * Chart data is loaded via ajax.\n *\n * @param {int|null} quizId The quiz Id.\n * @param {array|null} hoursFilter Array with hour ahead or behind preference.\n * @param {int|null} yearSelect Year selected.\n */\nexport const getCardCharts = (quizId, hoursFilter, yearSelect) => {\n cards.forEach((cardData) => {\n let cardElement = document.getElementById(cardData.cardId);\n let spinner = cardElement.getElementsByClassName('overlay-icon-container')[0];\n let chartBody = cardElement.getElementsByClassName('chart-body')[0];\n let values = {'call': cardData.call};\n // Add values to Object depending on dashboard type.\n if (hoursFilter) {\n values.hoursahead = hoursFilter[0];\n values.hoursbehind = hoursFilter[1];\n }\n if (quizId) {\n values.quiz = quizId;\n }\n if (yearSelect) {\n values.year = yearSelect;\n }\n let params = {'data': JSON.stringify(values)};\n\n spinner.classList.remove('hide'); // Show sinner if not already shown.\n Fragment.loadFragment('local_assessfreq', fragment, contextId, params)\n .done((response) => {\n let resObj = JSON.parse(response);\n if (resObj.hasdata === true) {\n let context = {\n 'withtable': true, 'chartdata': JSON.stringify(resObj.chart)\n };\n if (typeof cardData.aspect !== 'undefined') {\n context.aspect = cardData.aspect;\n }\n Templates.render(template, context).done((html, js) => {\n spinner.classList.add('hide'); // Hide spinner if not already hidden.\n // Load card body.\n Templates.replaceNodeContents(chartBody, html, js);\n }).fail(() => {\n Notification.exception(new Error('Failed to load chart template.'));\n return;\n });\n return;\n } else {\n Str.get_string('nodata', 'local_assessfreq').then((str) => {\n const noDatastr = document.createElement('h3');\n noDatastr.innerHTML = str;\n chartBody.innerHTML = noDatastr.outerHTML;\n spinner.classList.add('hide'); // Hide spinner if not already hidden.\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: nodata'));\n });\n }\n }).fail(() => {\n Notification.exception(new Error('Failed to load card.'));\n return;\n });\n });\n};\n\n/**\n * Initialise method for table handler.\n *\n * @param {array} cardsArray Cards array.\n * @param {int} contextIdChart The context id.\n * @param {string} fragmentChart Fragment name.\n * @param {string} templateChart Template name.\n */\nexport const init = (cardsArray, contextIdChart, fragmentChart, templateChart) => {\n cards = cardsArray;\n contextId = contextIdChart;\n fragment = fragmentChart;\n template = templateChart;\n};\n"],"names":["cards","contextId","fragment","template","quizId","hoursFilter","yearSelect","forEach","cardData","cardElement","document","getElementById","cardId","spinner","getElementsByClassName","chartBody","values","call","hoursahead","hoursbehind","quiz","year","params","JSON","stringify","classList","remove","loadFragment","done","response","resObj","parse","hasdata","context","chart","aspect","render","html","js","add","replaceNodeContents","fail","exception","Error","Str","get_string","then","str","noDatastr","createElement","innerHTML","outerHTML","catch","cardsArray","contextIdChart","fragmentChart","templateChart"],"mappings":";;;;;;;SA+BIA,MACAC,UACAC,SACAC,w6BAWyB,CAACC,OAAQC,YAAaC,cAC/CN,MAAMO,SAASC,eACPC,YAAcC,SAASC,eAAeH,SAASI,QAC/CC,QAAUJ,YAAYK,uBAAuB,0BAA0B,GACvEC,UAAYN,YAAYK,uBAAuB,cAAc,GAC7DE,OAAS,MAASR,SAASS,MAE3BZ,cACAW,OAAOE,WAAab,YAAY,GAChCW,OAAOG,YAAcd,YAAY,IAEjCD,SACAY,OAAOI,KAAOhB,QAEdE,aACAU,OAAOK,KAAOf,gBAEdgB,OAAS,MAASC,KAAKC,UAAUR,SAErCH,QAAQY,UAAUC,OAAO,0BAChBC,aAAa,mBAAoBzB,SAAUD,UAAWqB,QAC1DM,MAAMC,eACCC,OAASP,KAAKQ,MAAMF,cACD,IAAnBC,OAAOE,QAAkB,KACrBC,QAAU,YACG,YAAmBV,KAAKC,UAAUM,OAAOI,oBAE3B,IAApB1B,SAAS2B,SAChBF,QAAQE,OAAS3B,SAAS2B,gCAEpBC,OAAOjC,SAAU8B,SAASL,MAAK,CAACS,KAAMC,MAC5CzB,QAAQY,UAAUc,IAAI,2BAEZC,oBAAoBzB,UAAWsB,KAAMC,OAChDG,MAAK,2BACSC,UAAU,IAAIC,MAAM,sCAKrCC,IAAIC,WAAW,SAAU,oBAAoBC,MAAMC,YACzCC,UAAYtC,SAASuC,cAAc,MACzCD,UAAUE,UAAYH,IACtBhC,UAAUmC,UAAYF,UAAUG,UAChCtC,QAAQY,UAAUc,IAAI,WAEvBa,OAAM,2BACQV,UAAU,IAAIC,MAAM,wCAG1CF,MAAK,2BACSC,UAAU,IAAIC,MAAM,8CAc7B,CAACU,WAAYC,eAAgBC,cAAeC,iBAC5DxD,MAAQqD,WACRpD,UAAYqD,eACZpD,SAAWqD,cACXpD,SAAWqD"} \ No newline at end of file diff --git a/amd/build/chart_output_chartjs.min.js b/amd/build/chart_output_chartjs.min.js index 95ef0eed..f2ae8904 100644 --- a/amd/build/chart_output_chartjs.min.js +++ b/amd/build/chart_output_chartjs.min.js @@ -1,7 +1,6 @@ /** * Chart output for chart.js with custom override for aspect config. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/build/chart_output_chartjs.min.js.map b/amd/build/chart_output_chartjs.min.js.map index 86cb9e05..65756f59 100644 --- a/amd/build/chart_output_chartjs.min.js.map +++ b/amd/build/chart_output_chartjs.min.js.map @@ -1 +1 @@ -{"version":3,"file":"chart_output_chartjs.min.js","sources":["../src/chart_output_chartjs.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\n/**\n * Chart output for chart.js with custom override for aspect config.\n *\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['core/chart_output_chartjs'], function (Output) {\n\n /**\n * Module level variables.\n */\n var ChartOutput = {};\n var aspectRatio = false;\n var rtLegendoptions = false;\n\n /**\n * Overrride the config.\n *\n * @protected\n * @param {module:core/chart_axis} axis The axis.\n * @return {Object} The axis config.\n */\n Output.prototype._makeConfig = function () {\n var config = {\n type: this._getChartType(),\n data: {\n labels: this._cleanData(this._chart.getLabels()),\n datasets: this._makeDatasetsConfig()\n },\n options: {\n title: {\n display: this._chart.getTitle() !== null,\n text: this._cleanData(this._chart.getTitle())\n }\n }\n };\n var legendOptions = this._chart.getLegendOptions();\n if (legendOptions) {\n config.options.legend = legendOptions;\n }\n\n // Override legend options with those provided at run time.\n if (rtLegendoptions) {\n config.options.legend = rtLegendoptions;\n }\n\n this._chart.getXAxes().forEach(function (axis, i) {\n var axisLabels = axis.getLabels();\n\n config.options.scales = config.options.scales || {};\n config.options.scales.xAxes = config.options.scales.xAxes || [];\n config.options.scales.xAxes[i] = this._makeAxisConfig(axis, 'x', i);\n\n if (axisLabels !== null) {\n config.options.scales.xAxes[i].ticks.callback = function (value, index) {\n return axisLabels[index] || '';\n };\n }\n config.options.scales.xAxes[i].stacked = this._isStacked();\n }.bind(this));\n\n this._chart.getYAxes().forEach(function (axis, i) {\n var axisLabels = axis.getLabels();\n\n config.options.scales = config.options.scales || {};\n config.options.scales.yAxes = config.options.scales.yAxes || [];\n config.options.scales.yAxes[i] = this._makeAxisConfig(axis, 'y', i);\n\n if (axisLabels !== null) {\n config.options.scales.yAxes[i].ticks.callback = function (value) {\n return axisLabels[parseInt(value, 10)] || '';\n };\n }\n config.options.scales.yAxes[i].stacked = this._isStacked();\n }.bind(this));\n\n config.options.tooltips = {\n callbacks: {\n label: this._makeTooltip.bind(this)\n }\n };\n\n config.options.maintainAspectRatio = aspectRatio;\n\n return config;\n };\n\n /**\n * Get the aspect ratio setting and initialise the chart.\n */\n ChartOutput.init = function (chartImage, ChartInst, aspect, legend) {\n aspectRatio = aspect;\n rtLegendoptions = legend;\n new Output(chartImage, ChartInst);\n };\n\n return ChartOutput;\n\n});\n"],"names":["define","Output","ChartOutput","aspectRatio","rtLegendoptions","prototype","_makeConfig","config","type","this","_getChartType","data","labels","_cleanData","_chart","getLabels","datasets","_makeDatasetsConfig","options","title","display","getTitle","text","legendOptions","getLegendOptions","legend","getXAxes","forEach","axis","i","axisLabels","scales","xAxes","_makeAxisConfig","ticks","callback","value","index","stacked","_isStacked","bind","getYAxes","yAxes","parseInt","tooltips","callbacks","label","_makeTooltip","maintainAspectRatio","init","chartImage","ChartInst","aspect"],"mappings":";;;;;;;AAsBAA,+CAAO,CAAC,8BAA8B,SAAUC,YAKxCC,YAAc,GACdC,aAAc,EACdC,iBAAkB,SAStBH,OAAOI,UAAUC,YAAc,eACvBC,OAAS,CACTC,KAAMC,KAAKC,gBACXC,KAAM,CACFC,OAAQH,KAAKI,WAAWJ,KAAKK,OAAOC,aACpCC,SAAUP,KAAKQ,uBAEnBC,QAAS,CACLC,MAAO,CACHC,QAAoC,OAA3BX,KAAKK,OAAOO,WACrBC,KAAMb,KAAKI,WAAWJ,KAAKK,OAAOO,eAI1CE,cAAgBd,KAAKK,OAAOU,0BAC5BD,gBACAhB,OAAOW,QAAQO,OAASF,eAIxBnB,kBACAG,OAAOW,QAAQO,OAASrB,sBAGvBU,OAAOY,WAAWC,QAAQ,SAAUC,KAAMC,OACvCC,WAAaF,KAAKb,YAEtBR,OAAOW,QAAQa,OAASxB,OAAOW,QAAQa,QAAU,GACjDxB,OAAOW,QAAQa,OAAOC,MAAQzB,OAAOW,QAAQa,OAAOC,OAAS,GAC7DzB,OAAOW,QAAQa,OAAOC,MAAMH,GAAKpB,KAAKwB,gBAAgBL,KAAM,IAAKC,GAE9C,OAAfC,aACAvB,OAAOW,QAAQa,OAAOC,MAAMH,GAAGK,MAAMC,SAAW,SAAUC,MAAOC,cACtDP,WAAWO,QAAU,KAGpC9B,OAAOW,QAAQa,OAAOC,MAAMH,GAAGS,QAAU7B,KAAK8B,cAChDC,KAAK/B,YAEFK,OAAO2B,WAAWd,QAAQ,SAAUC,KAAMC,OACvCC,WAAaF,KAAKb,YAEtBR,OAAOW,QAAQa,OAASxB,OAAOW,QAAQa,QAAU,GACjDxB,OAAOW,QAAQa,OAAOW,MAAQnC,OAAOW,QAAQa,OAAOW,OAAS,GAC7DnC,OAAOW,QAAQa,OAAOW,MAAMb,GAAKpB,KAAKwB,gBAAgBL,KAAM,IAAKC,GAE9C,OAAfC,aACAvB,OAAOW,QAAQa,OAAOW,MAAMb,GAAGK,MAAMC,SAAW,SAAUC,cAC/CN,WAAWa,SAASP,MAAO,MAAQ,KAGlD7B,OAAOW,QAAQa,OAAOW,MAAMb,GAAGS,QAAU7B,KAAK8B,cAChDC,KAAK/B,OAEPF,OAAOW,QAAQ0B,SAAW,CACtBC,UAAW,CACPC,MAAOrC,KAAKsC,aAAaP,KAAK/B,QAItCF,OAAOW,QAAQ8B,oBAAsB7C,YAE9BI,QAMXL,YAAY+C,KAAO,SAAUC,WAAYC,UAAWC,OAAQ3B,QACxDtB,YAAciD,OACdhD,gBAAkBqB,WACdxB,OAAOiD,WAAYC,YAGpBjD"} \ No newline at end of file +{"version":3,"file":"chart_output_chartjs.min.js","sources":["../src/chart_output_chartjs.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\n/**\n * Chart output for chart.js with custom override for aspect config.\n *\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['core/chart_output_chartjs'], function (Output) {\n\n /**\n * Module level variables.\n */\n var ChartOutput = {};\n var aspectRatio = false;\n var rtLegendoptions = false;\n\n /**\n * Overrride the config.\n *\n * @protected\n * @return {Object} The axis config.\n */\n Output.prototype._makeConfig = function () {\n var config = {\n type: this._getChartType(),\n data: {\n labels: this._cleanData(this._chart.getLabels()),\n datasets: this._makeDatasetsConfig()\n },\n options: {\n title: {\n display: this._chart.getTitle() !== null,\n text: this._cleanData(this._chart.getTitle())\n }\n }\n };\n var legendOptions = this._chart.getLegendOptions();\n if (legendOptions) {\n config.options.legend = legendOptions;\n }\n\n // Override legend options with those provided at run time.\n if (rtLegendoptions) {\n config.options.legend = rtLegendoptions;\n }\n\n this._chart.getXAxes().forEach(function (axis, i) {\n var axisLabels = axis.getLabels();\n\n config.options.scales = config.options.scales || {};\n config.options.scales.xAxes = config.options.scales.xAxes || [];\n config.options.scales.xAxes[i] = this._makeAxisConfig(axis, 'x', i);\n\n if (axisLabels !== null) {\n config.options.scales.xAxes[i].ticks.callback = function (value, index) {\n return axisLabels[index] || '';\n };\n }\n config.options.scales.xAxes[i].stacked = this._isStacked();\n }.bind(this));\n\n this._chart.getYAxes().forEach(function (axis, i) {\n var axisLabels = axis.getLabels();\n\n config.options.scales = config.options.scales || {};\n config.options.scales.yAxes = config.options.scales.yAxes || [];\n config.options.scales.yAxes[i] = this._makeAxisConfig(axis, 'y', i);\n\n if (axisLabels !== null) {\n config.options.scales.yAxes[i].ticks.callback = function (value) {\n return axisLabels[parseInt(value, 10)] || '';\n };\n }\n config.options.scales.yAxes[i].stacked = this._isStacked();\n }.bind(this));\n\n config.options.tooltips = {\n callbacks: {\n label: this._makeTooltip.bind(this)\n }\n };\n\n config.options.maintainAspectRatio = aspectRatio;\n\n return config;\n };\n\n /**\n * Get the aspect ratio setting and initialise the chart.\n *\n * @param {string} chartImage The image to replace.\n * @param {object} ChartInst The chart instance.\n * @param {boolean} aspect The aspect ratio.\n * @param {object} legend The legend options.\n */\n ChartOutput.init = function (chartImage, ChartInst, aspect, legend) {\n aspectRatio = aspect;\n rtLegendoptions = legend;\n new Output(chartImage, ChartInst);\n };\n\n return ChartOutput;\n\n});\n"],"names":["define","Output","ChartOutput","aspectRatio","rtLegendoptions","prototype","_makeConfig","config","type","this","_getChartType","data","labels","_cleanData","_chart","getLabels","datasets","_makeDatasetsConfig","options","title","display","getTitle","text","legendOptions","getLegendOptions","legend","getXAxes","forEach","axis","i","axisLabels","scales","xAxes","_makeAxisConfig","ticks","callback","value","index","stacked","_isStacked","bind","getYAxes","yAxes","parseInt","tooltips","callbacks","label","_makeTooltip","maintainAspectRatio","init","chartImage","ChartInst","aspect"],"mappings":";;;;;;AAqBAA,+CAAO,CAAC,8BAA8B,SAAUC,YAKxCC,YAAc,GACdC,aAAc,EACdC,iBAAkB,SAQtBH,OAAOI,UAAUC,YAAc,eACvBC,OAAS,CACTC,KAAMC,KAAKC,gBACXC,KAAM,CACFC,OAAQH,KAAKI,WAAWJ,KAAKK,OAAOC,aACpCC,SAAUP,KAAKQ,uBAEnBC,QAAS,CACLC,MAAO,CACHC,QAAoC,OAA3BX,KAAKK,OAAOO,WACrBC,KAAMb,KAAKI,WAAWJ,KAAKK,OAAOO,eAI1CE,cAAgBd,KAAKK,OAAOU,0BAC5BD,gBACAhB,OAAOW,QAAQO,OAASF,eAIxBnB,kBACAG,OAAOW,QAAQO,OAASrB,sBAGvBU,OAAOY,WAAWC,QAAQ,SAAUC,KAAMC,OACvCC,WAAaF,KAAKb,YAEtBR,OAAOW,QAAQa,OAASxB,OAAOW,QAAQa,QAAU,GACjDxB,OAAOW,QAAQa,OAAOC,MAAQzB,OAAOW,QAAQa,OAAOC,OAAS,GAC7DzB,OAAOW,QAAQa,OAAOC,MAAMH,GAAKpB,KAAKwB,gBAAgBL,KAAM,IAAKC,GAE9C,OAAfC,aACAvB,OAAOW,QAAQa,OAAOC,MAAMH,GAAGK,MAAMC,SAAW,SAAUC,MAAOC,cACtDP,WAAWO,QAAU,KAGpC9B,OAAOW,QAAQa,OAAOC,MAAMH,GAAGS,QAAU7B,KAAK8B,cAChDC,KAAK/B,YAEFK,OAAO2B,WAAWd,QAAQ,SAAUC,KAAMC,OACvCC,WAAaF,KAAKb,YAEtBR,OAAOW,QAAQa,OAASxB,OAAOW,QAAQa,QAAU,GACjDxB,OAAOW,QAAQa,OAAOW,MAAQnC,OAAOW,QAAQa,OAAOW,OAAS,GAC7DnC,OAAOW,QAAQa,OAAOW,MAAMb,GAAKpB,KAAKwB,gBAAgBL,KAAM,IAAKC,GAE9C,OAAfC,aACAvB,OAAOW,QAAQa,OAAOW,MAAMb,GAAGK,MAAMC,SAAW,SAAUC,cAC/CN,WAAWa,SAASP,MAAO,MAAQ,KAGlD7B,OAAOW,QAAQa,OAAOW,MAAMb,GAAGS,QAAU7B,KAAK8B,cAChDC,KAAK/B,OAEPF,OAAOW,QAAQ0B,SAAW,CACtBC,UAAW,CACPC,MAAOrC,KAAKsC,aAAaP,KAAK/B,QAItCF,OAAOW,QAAQ8B,oBAAsB7C,YAE9BI,QAWXL,YAAY+C,KAAO,SAAUC,WAAYC,UAAWC,OAAQ3B,QACxDtB,YAAciD,OACdhD,gBAAkBqB,WACdxB,OAAOiD,WAAYC,YAGpBjD"} \ No newline at end of file diff --git a/amd/build/dashboard_assessment.min.js b/amd/build/dashboard_assessment.min.js index 835c060b..913662d3 100644 --- a/amd/build/dashboard_assessment.min.js +++ b/amd/build/dashboard_assessment.min.js @@ -3,7 +3,6 @@ define("local_assessfreq/dashboard_assessment",["exports","core/notification","l * Javascript for report card display and processing. * * @module local_assessfreq/dashboard_assessment - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */var contextid,yearselect,yearselectheatmap,metricselectheatmap,timeout;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_notification=_interopRequireDefault(_notification),_calendar=_interopRequireDefault(_calendar),ChartData=_interopRequireWildcard(ChartData),_dayview=_interopRequireDefault(_dayview),UserPreference=_interopRequireWildcard(UserPreference),_zoom_modal=_interopRequireDefault(_zoom_modal);var modulesJson="",heatmapOptionsJson="";const cards=[{cardId:"local-assessfreq-assess-due-month",call:"assess_by_month"},{cardId:"local-assessfreq-assess-by-activity",call:"assess_by_activity"},{cardId:"local-assessfreq-assess-due-month-student",call:"assess_by_month_student"}],yearButtonAction=event=>{event.preventDefault();var element=event.target;"a"===element.tagName.toLowerCase()&&element.dataset.year!==yearselect&&(yearselect=element.dataset.year,UserPreference.setUserPreference("local_assessfreq_overview_year_preference",yearselect),document.getElementById("local-assessfreq-report-overview").getElementsByClassName("local-assessfreq-year")[0].innerHTML=yearselect,ChartData.getCardCharts(0,null,yearselect))},updateHeatmapDebounce=()=>{clearTimeout(timeout),timeout=setTimeout(updateHeatmap(),750)},detailView=event=>{let element=event.target;"td"===element.tagName.toLowerCase()&&"true"===element.dataset.event&&_dayview.default.display(element.dataset.date)},updateHeatmap=()=>{for(var links=document.getElementById("local-assessfreq-heatmap-modules").getElementsByTagName("a"),modules=[],i=0;i{let heatmapOptions=JSON.parse(heatmapOptionsJson),year=parseInt(heatmapOptions.year),metric=heatmapOptions.metric,modules=heatmapOptions.modules,spinner=document.getElementById("local-assessfreq-report-heatmap").getElementsByClassName("overlay-icon-container")[0];spinner.classList.remove("hide"),_calendar.default.generate(year,0,11,metric,modules).then((calendar=>{let calendarContainer=document.getElementById("local-assessfreq-report-heatmap-months");calendarContainer.innerHTML=calendar.innerHTML,calendarContainer.addEventListener("click",detailView)})).then(_calendar.default.createHeatScale).then((heatScale=>{document.getElementById("local-assessfreq-report-heatmap-scale").innerHTML=heatScale.outerHTML,spinner.classList.add("hide")})).catch((()=>{_notification.default.exception(new Error("Failed to calendar."))}))})(),(_ref=>{let{year:year,metric:metric,modules:modules}=_ref,downloadForm=document.getElementById("local-assessfreq-heatmap-form"),formElements=downloadForm.elements,toRemove=new Array;0===modules.length&&(modules=["all"]);for(let i=0;i{event.preventDefault();var element=event.target;"a"===element.tagName.toLowerCase()&&element.dataset.year!==yearselectheatmap&&(yearselectheatmap=element.dataset.year,UserPreference.setUserPreference("local_assessfreq_heatmap_year_preference",yearselectheatmap),document.getElementById("local-assessfreq-report-heatmap").getElementsByClassName("local-assessfreq-year")[0].innerHTML=yearselectheatmap,updateHeatmapDebounce())},metricHeatmapButtonAction=event=>{event.preventDefault();var element=event.target;"a"===element.tagName.toLowerCase()&&element.dataset.metric!==metricselectheatmap&&(metricselectheatmap=element.dataset.metric,UserPreference.setUserPreference("local_assessfreq_heatmap_metric_preference",metricselectheatmap),updateHeatmapDebounce())},triggerZoomGraph=event=>{let call=event.target.closest("div").dataset.call,params={data:JSON.stringify({year:yearselect,call:call})};_zoom_modal.default.zoomGraph(event,params,"get_chart")};_exports.init=context=>{contextid=context;let cardsYearSelectElement=document.getElementById("local-assessfreq-cards-year");yearselect=cardsYearSelectElement.getElementsByClassName("active")[0].dataset.year,cardsYearSelectElement.addEventListener("click",yearButtonAction);let cardsYearSelectHeatmapElement=document.getElementById("local-assessfreq-heatmap-year");yearselectheatmap=cardsYearSelectHeatmapElement.getElementsByClassName("active")[0].dataset.year,cardsYearSelectHeatmapElement.addEventListener("click",yearHeatmapButtonAction);let cardsMetricSelectHeatmapElement=document.getElementById("local-assessfreq-heatmap-metrics");metricselectheatmap=cardsMetricSelectHeatmapElement.getElementsByClassName("active")[0].dataset.metric,cardsMetricSelectHeatmapElement.addEventListener("click",metricHeatmapButtonAction),(element=>{for(var links=element.getElementsByTagName("a"),all=links[0],i=0;i.\n\n/**\n * Javascript for report card display and processing.\n *\n * @module local_assessfreq/dashboard_assessment\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Notification from 'core/notification';\nimport Calendar from 'local_assessfreq/calendar';\nimport * as ChartData from 'local_assessfreq/chart_data';\nimport Dayview from 'local_assessfreq/dayview';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\nimport ZoomModal from 'local_assessfreq/zoom_modal';\n\n/**\n * Module level variables.\n */\nvar contextid;\nvar yearselect;\nvar yearselectheatmap;\nvar metricselectheatmap;\nvar timeout;\nvar modulesJson = '';\nvar heatmapOptionsJson = '';\n\nconst cards = [\n {cardId: 'local-assessfreq-assess-due-month', call: 'assess_by_month'},\n {cardId: 'local-assessfreq-assess-by-activity', call: 'assess_by_activity'},\n {cardId: 'local-assessfreq-assess-due-month-student', call: 'assess_by_month_student'}\n];\n\n/**\n * Get and process the selected year from the dropdown,\n * and update the corresponding user perference.\n *\n * @param {event} event The triggered event for the element.\n */\nconst yearButtonAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.tagName.toLowerCase() === 'a' && element.dataset.year !== yearselect) { // Only act on certain elements.\n yearselect = element.dataset.year;\n\n // Save selection as a user preference.\n UserPreference.setUserPreference('local_assessfreq_overview_year_preference', yearselect);\n\n // Update card data based on selected year.\n var yeartitle = document.getElementById('local-assessfreq-report-overview')\n .getElementsByClassName('local-assessfreq-year')[0];\n yeartitle.innerHTML = yearselect;\n\n ChartData.getCardCharts(0, null, yearselect); // Process loading for the assessment cards.\n }\n};\n\n/**\n * Quick and dirty debounce method for the heatmap settings menu.\n * This stops the ajax method that updates the heatmap from being updated\n * while the user is still checking options.\n *\n */\nconst updateHeatmapDebounce = () => {\n clearTimeout(timeout);\n timeout = setTimeout(updateHeatmap(), 750);\n};\n\n/**\n * Display heatmap calendar.\n *\n * @param {event} event The triggered event for the element.\n */\nconst detailView = (event) => {\n let element = event.target;\n if (element.tagName.toLowerCase() === 'td' && element.dataset.event === 'true') { // Only act on certain elements.\n Dayview.display(element.dataset.date);\n }\n};\n\n/**\n * Start heatmap generation.\n *\n */\nconst generateHeatmap = () => {\n let heatmapOptions = JSON.parse(heatmapOptionsJson);\n let year = parseInt(heatmapOptions.year);\n let metric = heatmapOptions.metric;\n let modules = heatmapOptions.modules;\n let heatmapContainer = document.getElementById('local-assessfreq-report-heatmap');\n let spinner = heatmapContainer.getElementsByClassName('overlay-icon-container')[0];\n\n spinner.classList.remove('hide'); // Show spinner if not already shown.\n\n Calendar.generate(year, 0, 11, metric, modules)\n .then(calendar => {\n let calendarContainer = document.getElementById('local-assessfreq-report-heatmap-months');\n calendarContainer.innerHTML = calendar.innerHTML;\n calendarContainer.addEventListener('click', detailView);\n })\n .then(Calendar.createHeatScale)\n .then((heatScale) => {\n let heatScaleContainer = document.getElementById('local-assessfreq-report-heatmap-scale');\n heatScaleContainer.innerHTML = heatScale.outerHTML;\n spinner.classList.add('hide'); // Hide sinner if not already hidden.\n })\n .catch(() => {\n Notification.exception(new Error('Failed to calendar.'));\n return;\n });\n};\n\nconst updateDownload = ({year, metric, modules}) => {\n let downloadForm = document.getElementById('local-assessfreq-heatmap-form');\n let formElements = downloadForm.elements;\n let toRemove = new Array();\n\n if (modules.length === 0) {\n modules = ['all'];\n }\n\n for (let i = 0; i < formElements.length; i++) {\n if (formElements[i] === undefined) {\n continue;\n }\n // Update year field.\n if ((formElements[i].type === 'hidden') && (formElements[i].name === 'year')) {\n formElements[i].value = year;\n continue;\n }\n\n // Update metric field.\n if ((formElements[i].type === 'hidden') && (formElements[i].name === 'metric')) {\n formElements[i].value = metric;\n continue;\n }\n\n // Update module fields.\n if ((formElements[i].type === 'hidden') && (formElements[i].name.startsWith('modules'))) {\n toRemove.push(formElements[i]);\n continue;\n }\n }\n\n for (const element of toRemove) {\n element.remove();\n }\n\n for (let i = 0; i < modules.length; i++) {\n let input = document.createElement('input');\n input.type = 'hidden';\n input.name = 'modules[' + modules[i] + ']';\n input.value = modules[i];\n\n downloadForm.appendChild(input);\n }\n};\n\n/**\n * Update the heatmap based on the current filter settings.\n *\n */\nconst updateHeatmap = () => {\n // Get current state of select menu items.\n var cardsModulesSelectHeatmapElement = document.getElementById('local-assessfreq-heatmap-modules');\n var links = cardsModulesSelectHeatmapElement.getElementsByTagName('a');\n var modules = [];\n\n for (var i = 0; i < links.length; i++) {\n if (links[i].classList.contains('active')) {\n let module = links[i].dataset.module;\n modules.push(module);\n }\n }\n\n // Save selection as a user preference.\n if (modulesJson !== JSON.stringify(modules)) {\n modulesJson = JSON.stringify(modules);\n UserPreference.setUserPreference('local_assessfreq_heatmap_modules_preference', modulesJson);\n }\n\n // Build settings object.\n var optionsObj = {\n 'year': yearselectheatmap,\n 'metric': metricselectheatmap,\n 'modules': modules\n };\n\n var optionsJson = JSON.stringify(optionsObj);\n\n if (optionsJson !== heatmapOptionsJson) { // Compare to global to see if there are any changes.\n // If list has changed fetch heatmap and update user preference.\n heatmapOptionsJson = optionsJson;\n generateHeatmap();\n\n // Update the download options.\n updateDownload(optionsObj);\n }\n};\n\n/**\n * Get and process the selected year from the dropdown for the heatmap display,\n * and update the corresponding user preference.\n *\n * @param {event} event The triggered event for the element.\n */\nconst yearHeatmapButtonAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.tagName.toLowerCase() === 'a' && element.dataset.year !== yearselectheatmap) { // Only act on certain elements.\n yearselectheatmap = element.dataset.year;\n\n // Save selection as a user preference.\n UserPreference.setUserPreference('local_assessfreq_heatmap_year_preference', yearselectheatmap);\n\n // Update card data based on selected year.\n var yeartitle = document.getElementById('local-assessfreq-report-heatmap')\n .getElementsByClassName('local-assessfreq-year')[0];\n yeartitle.innerHTML = yearselectheatmap;\n\n updateHeatmapDebounce(); // Call function to update heatmap.\n }\n};\n\n/**\n * Get and process the selected assessment metric from the dropdown for the heatmap display,\n * and update the corresponding user preference.\n *\n * @param {event} event The triggered event for the element.\n */\nconst metricHeatmapButtonAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.tagName.toLowerCase() === 'a' && element.dataset.metric !== metricselectheatmap) {\n metricselectheatmap = element.dataset.metric;\n\n // Save selection as a user preference.\n UserPreference.setUserPreference('local_assessfreq_heatmap_metric_preference', metricselectheatmap);\n\n updateHeatmapDebounce(); // Call function to update heatmap.\n }\n};\n\n/**\n * Add the event listeners to the modules in the module select dropdown.\n *\n * @param {Object} element The dropdown HTML element that contains the list of modules as links.\n */\nconst moduleListChildrenEvents = (element) => {\n var links = element.getElementsByTagName('a');\n var all = links[0];\n\n for (var i = 0; i < links.length; i++) {\n let module = links[i].dataset.module;\n\n if (module.toLowerCase() === 'all') {\n links[i].addEventListener('click', function (event) {\n event.preventDefault();\n // Remove active class from all other links.\n for (var j = 0; j < links.length; j++) {\n links[j].classList.remove('active');\n }\n updateHeatmapDebounce(); // Call function to update heatmap.\n });\n } else if (module.toLowerCase() === 'close') {\n links[i].addEventListener('click', function (event) {\n event.preventDefault();\n event.stopPropagation();\n\n var dropdownmenu = document.getElementById('local-assessfreq-heatmap-modules-filter');\n dropdownmenu.classList.remove('show');\n\n updateHeatmapDebounce(); // Call function to update heatmap.\n });\n } else {\n links[i].addEventListener('click', function (event) {\n event.preventDefault();\n event.stopPropagation();\n\n all.classList.remove('active');\n\n event.target.classList.toggle('active');\n updateHeatmapDebounce();\n });\n }\n }\n};\n\n/**\n * Thin wrapper to add extra data to click event.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst triggerZoomGraph = (event) => {\n let call = event.target.closest('div').dataset.call;\n let params = {'data': JSON.stringify({'year': yearselect, 'call': call})};\n let method = 'get_chart';\n\n ZoomModal.zoomGraph(event, params, method);\n};\n\n/**\n * Initialise method for report card rendering.\n *\n * @param {integer} context The current context id.\n */\nexport const init = (context) => {\n contextid = context;\n\n // Set up event listener and related actions for year dropdown on report cards.\n let cardsYearSelectElement = document.getElementById('local-assessfreq-cards-year');\n yearselect = cardsYearSelectElement.getElementsByClassName('active')[0].dataset.year;\n cardsYearSelectElement.addEventListener('click', yearButtonAction);\n\n // Set up event listener and related actions for year dropdown on heatmp.\n let cardsYearSelectHeatmapElement = document.getElementById('local-assessfreq-heatmap-year');\n yearselectheatmap = cardsYearSelectHeatmapElement.getElementsByClassName('active')[0].dataset.year;\n cardsYearSelectHeatmapElement.addEventListener('click', yearHeatmapButtonAction);\n\n // Set up event listener and related actions for metric dropdown on heatmp.\n let cardsMetricSelectHeatmapElement = document.getElementById('local-assessfreq-heatmap-metrics');\n metricselectheatmap = cardsMetricSelectHeatmapElement.getElementsByClassName('active')[0].dataset.metric;\n cardsMetricSelectHeatmapElement.addEventListener('click', metricHeatmapButtonAction);\n\n // Set up event listener and related actions for module dropdown on heatmp.\n let cardsModulesSelectHeatmapElement = document.getElementById('local-assessfreq-heatmap-modules');\n moduleListChildrenEvents(cardsModulesSelectHeatmapElement);\n\n // Set up zoom event listeners.\n let dueMonthZoom = document.getElementById('local-assessfreq-assess-due-month-zoom');\n dueMonthZoom.addEventListener('click', triggerZoomGraph);\n\n let dueActivityZoom = document.getElementById('local-assessfreq-assess-by-activity-zoom');\n dueActivityZoom.addEventListener('click', triggerZoomGraph);\n\n let dueStudentZoom = document.getElementById('local-assessfreq-assess-due-month-student-zoom');\n dueStudentZoom.addEventListener('click', triggerZoomGraph);\n\n // Create the zoom modal.\n ZoomModal.init(context);\n\n // Setup the dayview modal.\n Dayview.init();\n\n // Setup the chart data for each card.\n ChartData.init(cards, contextid, 'get_chart', 'core/chart');\n\n // Process loading for the assessment cards.\n ChartData.getCardCharts(0, null, yearselect);\n\n // Get the data for the heatmap.\n updateHeatmap();\n\n};\n"],"names":["contextid","yearselect","yearselectheatmap","metricselectheatmap","timeout","modulesJson","heatmapOptionsJson","cards","cardId","call","yearButtonAction","event","preventDefault","element","target","tagName","toLowerCase","dataset","year","UserPreference","setUserPreference","document","getElementById","getElementsByClassName","innerHTML","ChartData","getCardCharts","updateHeatmapDebounce","clearTimeout","setTimeout","updateHeatmap","detailView","display","date","links","getElementsByTagName","modules","i","length","classList","contains","module","push","JSON","stringify","optionsObj","optionsJson","heatmapOptions","parse","parseInt","metric","spinner","remove","generate","then","calendar","calendarContainer","addEventListener","Calendar","createHeatScale","heatScale","outerHTML","add","catch","exception","Error","generateHeatmap","_ref","downloadForm","formElements","elements","toRemove","Array","undefined","type","name","startsWith","value","input","createElement","appendChild","updateDownload","yearHeatmapButtonAction","metricHeatmapButtonAction","triggerZoomGraph","closest","params","zoomGraph","context","cardsYearSelectElement","cardsYearSelectHeatmapElement","cardsMetricSelectHeatmapElement","all","j","stopPropagation","toggle","moduleListChildrenEvents","init"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"dashboard_assessment.min.js","sources":["../src/dashboard_assessment.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\n/**\n * Javascript for report card display and processing.\n *\n * @module local_assessfreq/dashboard_assessment\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Notification from 'core/notification';\nimport Calendar from 'local_assessfreq/calendar';\nimport * as ChartData from 'local_assessfreq/chart_data';\nimport Dayview from 'local_assessfreq/dayview';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\nimport ZoomModal from 'local_assessfreq/zoom_modal';\n\n/**\n * Module level variables.\n */\nvar contextid;\nvar yearselect;\nvar yearselectheatmap;\nvar metricselectheatmap;\nvar timeout;\nvar modulesJson = '';\nvar heatmapOptionsJson = '';\n\nconst cards = [\n {cardId: 'local-assessfreq-assess-due-month', call: 'assess_by_month'},\n {cardId: 'local-assessfreq-assess-by-activity', call: 'assess_by_activity'},\n {cardId: 'local-assessfreq-assess-due-month-student', call: 'assess_by_month_student'}\n];\n\n/**\n * Get and process the selected year from the dropdown,\n * and update the corresponding user perference.\n *\n * @param {event} event The triggered event for the element.\n */\nconst yearButtonAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.tagName.toLowerCase() === 'a' && element.dataset.year !== yearselect) { // Only act on certain elements.\n yearselect = element.dataset.year;\n\n // Save selection as a user preference.\n UserPreference.setUserPreference('local_assessfreq_overview_year_preference', yearselect);\n\n // Update card data based on selected year.\n var yeartitle = document.getElementById('local-assessfreq-report-overview')\n .getElementsByClassName('local-assessfreq-year')[0];\n yeartitle.innerHTML = yearselect;\n\n ChartData.getCardCharts(0, null, yearselect); // Process loading for the assessment cards.\n }\n};\n\n/**\n * Quick and dirty debounce method for the heatmap settings menu.\n * This stops the ajax method that updates the heatmap from being updated\n * while the user is still checking options.\n *\n */\nconst updateHeatmapDebounce = () => {\n clearTimeout(timeout);\n timeout = setTimeout(updateHeatmap(), 750);\n};\n\n/**\n * Display heatmap calendar.\n *\n * @param {event} event The triggered event for the element.\n */\nconst detailView = (event) => {\n let element = event.target;\n if (element.tagName.toLowerCase() === 'td' && element.dataset.event === 'true') { // Only act on certain elements.\n Dayview.display(element.dataset.date);\n }\n};\n\n/**\n * Start heatmap generation.\n *\n */\nconst generateHeatmap = () => {\n let heatmapOptions = JSON.parse(heatmapOptionsJson);\n let year = parseInt(heatmapOptions.year);\n let metric = heatmapOptions.metric;\n let modules = heatmapOptions.modules;\n let heatmapContainer = document.getElementById('local-assessfreq-report-heatmap');\n let spinner = heatmapContainer.getElementsByClassName('overlay-icon-container')[0];\n\n spinner.classList.remove('hide'); // Show spinner if not already shown.\n\n Calendar.generate(year, 0, 11, metric, modules)\n .then(calendar => {\n let calendarContainer = document.getElementById('local-assessfreq-report-heatmap-months');\n calendarContainer.innerHTML = calendar.innerHTML;\n calendarContainer.addEventListener('click', detailView);\n })\n .then(Calendar.createHeatScale)\n .then((heatScale) => {\n let heatScaleContainer = document.getElementById('local-assessfreq-report-heatmap-scale');\n heatScaleContainer.innerHTML = heatScale.outerHTML;\n spinner.classList.add('hide'); // Hide sinner if not already hidden.\n })\n .catch(() => {\n Notification.exception(new Error('Failed to calendar.'));\n return;\n });\n};\n\nconst updateDownload = ({year, metric, modules}) => {\n let downloadForm = document.getElementById('local-assessfreq-heatmap-form');\n let formElements = downloadForm.elements;\n let toRemove = new Array();\n\n if (modules.length === 0) {\n modules = ['all'];\n }\n\n for (let i = 0; i < formElements.length; i++) {\n if (formElements[i] === undefined) {\n continue;\n }\n // Update year field.\n if ((formElements[i].type === 'hidden') && (formElements[i].name === 'year')) {\n formElements[i].value = year;\n continue;\n }\n\n // Update metric field.\n if ((formElements[i].type === 'hidden') && (formElements[i].name === 'metric')) {\n formElements[i].value = metric;\n continue;\n }\n\n // Update module fields.\n if ((formElements[i].type === 'hidden') && (formElements[i].name.startsWith('modules'))) {\n toRemove.push(formElements[i]);\n continue;\n }\n }\n\n for (const element of toRemove) {\n element.remove();\n }\n\n for (let i = 0; i < modules.length; i++) {\n let input = document.createElement('input');\n input.type = 'hidden';\n input.name = 'modules[' + modules[i] + ']';\n input.value = modules[i];\n\n downloadForm.appendChild(input);\n }\n};\n\n/**\n * Update the heatmap based on the current filter settings.\n *\n */\nconst updateHeatmap = () => {\n // Get current state of select menu items.\n var cardsModulesSelectHeatmapElement = document.getElementById('local-assessfreq-heatmap-modules');\n var links = cardsModulesSelectHeatmapElement.getElementsByTagName('a');\n var modules = [];\n\n for (var i = 0; i < links.length; i++) {\n if (links[i].classList.contains('active')) {\n let module = links[i].dataset.module;\n modules.push(module);\n }\n }\n\n // Save selection as a user preference.\n if (modulesJson !== JSON.stringify(modules)) {\n modulesJson = JSON.stringify(modules);\n UserPreference.setUserPreference('local_assessfreq_heatmap_modules_preference', modulesJson);\n }\n\n // Build settings object.\n var optionsObj = {\n 'year': yearselectheatmap,\n 'metric': metricselectheatmap,\n 'modules': modules\n };\n\n var optionsJson = JSON.stringify(optionsObj);\n\n if (optionsJson !== heatmapOptionsJson) { // Compare to global to see if there are any changes.\n // If list has changed fetch heatmap and update user preference.\n heatmapOptionsJson = optionsJson;\n generateHeatmap();\n\n // Update the download options.\n updateDownload(optionsObj);\n }\n};\n\n/**\n * Get and process the selected year from the dropdown for the heatmap display,\n * and update the corresponding user preference.\n *\n * @param {event} event The triggered event for the element.\n */\nconst yearHeatmapButtonAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.tagName.toLowerCase() === 'a' && element.dataset.year !== yearselectheatmap) { // Only act on certain elements.\n yearselectheatmap = element.dataset.year;\n\n // Save selection as a user preference.\n UserPreference.setUserPreference('local_assessfreq_heatmap_year_preference', yearselectheatmap);\n\n // Update card data based on selected year.\n var yeartitle = document.getElementById('local-assessfreq-report-heatmap')\n .getElementsByClassName('local-assessfreq-year')[0];\n yeartitle.innerHTML = yearselectheatmap;\n\n updateHeatmapDebounce(); // Call function to update heatmap.\n }\n};\n\n/**\n * Get and process the selected assessment metric from the dropdown for the heatmap display,\n * and update the corresponding user preference.\n *\n * @param {event} event The triggered event for the element.\n */\nconst metricHeatmapButtonAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.tagName.toLowerCase() === 'a' && element.dataset.metric !== metricselectheatmap) {\n metricselectheatmap = element.dataset.metric;\n\n // Save selection as a user preference.\n UserPreference.setUserPreference('local_assessfreq_heatmap_metric_preference', metricselectheatmap);\n\n updateHeatmapDebounce(); // Call function to update heatmap.\n }\n};\n\n/**\n * Add the event listeners to the modules in the module select dropdown.\n *\n * @param {Object} element The dropdown HTML element that contains the list of modules as links.\n */\nconst moduleListChildrenEvents = (element) => {\n var links = element.getElementsByTagName('a');\n var all = links[0];\n\n for (var i = 0; i < links.length; i++) {\n let module = links[i].dataset.module;\n\n if (module.toLowerCase() === 'all') {\n links[i].addEventListener('click', function (event) {\n event.preventDefault();\n // Remove active class from all other links.\n for (var j = 0; j < links.length; j++) {\n links[j].classList.remove('active');\n }\n updateHeatmapDebounce(); // Call function to update heatmap.\n });\n } else if (module.toLowerCase() === 'close') {\n links[i].addEventListener('click', function (event) {\n event.preventDefault();\n event.stopPropagation();\n\n var dropdownmenu = document.getElementById('local-assessfreq-heatmap-modules-filter');\n dropdownmenu.classList.remove('show');\n\n updateHeatmapDebounce(); // Call function to update heatmap.\n });\n } else {\n links[i].addEventListener('click', function (event) {\n event.preventDefault();\n event.stopPropagation();\n\n all.classList.remove('active');\n\n event.target.classList.toggle('active');\n updateHeatmapDebounce();\n });\n }\n }\n};\n\n/**\n * Thin wrapper to add extra data to click event.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst triggerZoomGraph = (event) => {\n let call = event.target.closest('div').dataset.call;\n let params = {'data': JSON.stringify({'year': yearselect, 'call': call})};\n let method = 'get_chart';\n\n ZoomModal.zoomGraph(event, params, method);\n};\n\n/**\n * Initialise method for report card rendering.\n *\n * @param {integer} context The current context id.\n */\nexport const init = (context) => {\n contextid = context;\n\n // Set up event listener and related actions for year dropdown on report cards.\n let cardsYearSelectElement = document.getElementById('local-assessfreq-cards-year');\n yearselect = cardsYearSelectElement.getElementsByClassName('active')[0].dataset.year;\n cardsYearSelectElement.addEventListener('click', yearButtonAction);\n\n // Set up event listener and related actions for year dropdown on heatmp.\n let cardsYearSelectHeatmapElement = document.getElementById('local-assessfreq-heatmap-year');\n yearselectheatmap = cardsYearSelectHeatmapElement.getElementsByClassName('active')[0].dataset.year;\n cardsYearSelectHeatmapElement.addEventListener('click', yearHeatmapButtonAction);\n\n // Set up event listener and related actions for metric dropdown on heatmp.\n let cardsMetricSelectHeatmapElement = document.getElementById('local-assessfreq-heatmap-metrics');\n metricselectheatmap = cardsMetricSelectHeatmapElement.getElementsByClassName('active')[0].dataset.metric;\n cardsMetricSelectHeatmapElement.addEventListener('click', metricHeatmapButtonAction);\n\n // Set up event listener and related actions for module dropdown on heatmp.\n let cardsModulesSelectHeatmapElement = document.getElementById('local-assessfreq-heatmap-modules');\n moduleListChildrenEvents(cardsModulesSelectHeatmapElement);\n\n // Set up zoom event listeners.\n let dueMonthZoom = document.getElementById('local-assessfreq-assess-due-month-zoom');\n dueMonthZoom.addEventListener('click', triggerZoomGraph);\n\n let dueActivityZoom = document.getElementById('local-assessfreq-assess-by-activity-zoom');\n dueActivityZoom.addEventListener('click', triggerZoomGraph);\n\n let dueStudentZoom = document.getElementById('local-assessfreq-assess-due-month-student-zoom');\n dueStudentZoom.addEventListener('click', triggerZoomGraph);\n\n // Create the zoom modal.\n ZoomModal.init(context);\n\n // Setup the dayview modal.\n Dayview.init();\n\n // Setup the chart data for each card.\n ChartData.init(cards, contextid, 'get_chart', 'core/chart');\n\n // Process loading for the assessment cards.\n ChartData.getCardCharts(0, null, yearselect);\n\n // Get the data for the heatmap.\n updateHeatmap();\n\n};\n"],"names":["contextid","yearselect","yearselectheatmap","metricselectheatmap","timeout","modulesJson","heatmapOptionsJson","cards","cardId","call","yearButtonAction","event","preventDefault","element","target","tagName","toLowerCase","dataset","year","UserPreference","setUserPreference","document","getElementById","getElementsByClassName","innerHTML","ChartData","getCardCharts","updateHeatmapDebounce","clearTimeout","setTimeout","updateHeatmap","detailView","display","date","links","getElementsByTagName","modules","i","length","classList","contains","module","push","JSON","stringify","optionsObj","optionsJson","heatmapOptions","parse","parseInt","metric","spinner","remove","generate","then","calendar","calendarContainer","addEventListener","Calendar","createHeatScale","heatScale","outerHTML","add","catch","exception","Error","generateHeatmap","_ref","downloadForm","formElements","elements","toRemove","Array","undefined","type","name","startsWith","value","input","createElement","appendChild","updateDownload","yearHeatmapButtonAction","metricHeatmapButtonAction","triggerZoomGraph","closest","params","zoomGraph","context","cardsYearSelectElement","cardsYearSelectHeatmapElement","cardsMetricSelectHeatmapElement","all","j","stopPropagation","toggle","moduleListChildrenEvents","init"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/dashboard_quiz.min.js b/amd/build/dashboard_quiz.min.js index 2199f143..2682290f 100644 --- a/amd/build/dashboard_quiz.min.js +++ b/amd/build/dashboard_quiz.min.js @@ -3,7 +3,6 @@ define("local_assessfreq/dashboard_quiz",["exports","core/ajax","core/notificati * Javascript for report card display and processing. * * @module local_assessfreq/dashboard_quiz - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_ajax=_interopRequireDefault(_ajax),_notification=_interopRequireDefault(_notification),Str=_interopRequireWildcard(Str),_templates=_interopRequireDefault(_templates),ChartData=_interopRequireWildcard(ChartData),FormModal=_interopRequireWildcard(FormModal),_override_modal=_interopRequireDefault(_override_modal),TableHandler=_interopRequireWildcard(TableHandler),UserPreference=_interopRequireWildcard(UserPreference),ZoomModal=_interopRequireWildcard(ZoomModal);var contextid,counterid,selectQuizStr="",quizId=0,refreshPeriod=60;const cards=[{cardId:"local-assessfreq-quiz-summary-graph",call:"participant_summary",aspect:!0},{cardId:"local-assessfreq-quiz-summary-trend",call:"participant_trend",aspect:!1}],refreshCounter=function(){let reset=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],progressElement=document.getElementById("local-assessfreq-period-progress");!0===reset&&(clearInterval(counterid),counterid=null,progressElement.setAttribute("style","width: 100%"),progressElement.setAttribute("aria-valuenow",100)),counterid||(counterid=setInterval((()=>{let progressWidthAria=progressElement.getAttribute("aria-valuenow");const progressStep=100/refreshPeriod;progressWidthAria-progressStep>0?(progressElement.setAttribute("style","width: "+(progressWidthAria-progressStep)+"%"),progressElement.setAttribute("aria-valuenow",progressWidthAria-progressStep)):(clearInterval(counterid),counterid=null,progressElement.setAttribute("style","width: 100%"),progressElement.setAttribute("aria-valuenow",100),processDashboard(quizId),refreshCounter())}),1e3))},processDashboard=quiz=>{quizId=quiz;let titleElement=document.getElementById("local-assessfreq-quiz-title");titleElement.innerHTML=selectQuizStr,_ajax.default.call([{methodname:"local_assessfreq_get_quiz_data",args:{quizid:quiz}}])[0].then((response=>{let quizArray=JSON.parse(response),cardsElement=document.getElementById("local-assessfreq-quiz-dashboard-cards-deck"),trendElement=document.getElementById("local-assessfreq-quiz-dashboard-participant-trend-deck"),summarySpinner=document.getElementById("local-assessfreq-quiz-summary-card").getElementsByClassName("overlay-icon-container")[0],tableElement=document.getElementById("local-assessfreq-quiz-table"),periodElement=document.getElementById("local-assessfreq-period-container"),tableSearchInputElement=document.getElementById("local-assessfreq-quiz-student-table-search"),tableSearchResetElement=document.getElementById("local-assessfreq-quiz-student-table-search-reset"),tableSearchRowsElement=document.getElementById("local-assessfreq-quiz-student-table-rows"),quizLink=document.createElement("a");quizLink.href=quizArray.url,quizLink.innerHTML='',titleElement.innerHTML=quizArray.name+" ",titleElement.appendChild(quizLink);const currentdUrl=new URL(window.location.href),newUrl=currentdUrl.origin+currentdUrl.pathname+"?id="+quizId;history.pushState({},"",newUrl),Str.get_string("dashboard:quiztitle","local_assessfreq",{quiz:quizArray.name,course:quizArray.courseshortname}).then((str=>{document.title=str})).catch((()=>{_notification.default.exception(new Error("Failed to load string: dashboard:quiztitle"))})),_templates.default.render("local_assessfreq/quiz-summary-card-content",quizArray).done((html=>{summarySpinner.classList.add("hide");let contentcontainer=document.getElementById("local-assessfreq-quiz-summary-card-content");_templates.default.replaceNodeContents(contentcontainer,html,"")})).fail((()=>{_notification.default.exception(new Error("Failed to load quiz summary template."))})),cardsElement.classList.remove("hide"),trendElement.classList.remove("hide"),tableElement.classList.remove("hide"),periodElement.classList.remove("hide"),ChartData.getCardCharts(quizId),TableHandler.getTable(quizId),refreshCounter(),tableSearchInputElement.addEventListener("keyup",TableHandler.tableSearch),tableSearchInputElement.addEventListener("paste",TableHandler.tableSearch),tableSearchResetElement.addEventListener("click",TableHandler.tableSearchReset),tableSearchRowsElement.addEventListener("click",TableHandler.tableSearchRowSet)})).fail((()=>{_notification.default.exception(new Error("Failed to get quiz data"))}))},refreshAction=event=>{event.preventDefault();var element=event.target;null!==element.closest("button")&&"local-assessfreq-refresh-quiz-dashboard"===element.closest("button").id?(refreshCounter(!0),processDashboard(quizId)):"a"===element.tagName.toLowerCase()&&(refreshPeriod=element.dataset.period,refreshCounter(!0),UserPreference.setUserPreference("local_assessfreq_quiz_refresh_preference",refreshPeriod))},triggerZoomGraph=event=>{let call=event.target.closest("div").dataset.call,params={data:JSON.stringify({quiz:quizId,call:call})};ZoomModal.zoomGraph(event,params,"get_quiz_chart")};_exports.init=(context,quiz)=>{contextid=context,FormModal.init(context,processDashboard),ZoomModal.init(context),_override_modal.default.init(context,processDashboard),TableHandler.init(quizId,contextid,"local-assessfreq-quiz-student-table","local-assessfreq-quiz-table","get_student_table","local_assessfreq_quiz_table_rows_preference","local-assessfreq-quiz-student-table-search","local_assessfreq_student_table","local_assessfreq_set_table_preference"),ChartData.init(cards,context,"get_quiz_chart","local_assessfreq/chart"),Str.get_string("loadingquiztitle","local_assessfreq").then((str=>{selectQuizStr=str})).catch((()=>{_notification.default.exception(new Error("Failed to load string: loadingquiz"))})).then((()=>{quiz>0&&(quizId=quiz,processDashboard(quiz))})),UserPreference.getUserPreference("local_assessfreq_quiz_refresh_preference").then((response=>{refreshPeriod=response.preferences[0].value?response.preferences[0].value:60})).fail((()=>{_notification.default.exception(new Error("Failed to get use preference: refresh"))})),document.getElementById("local-assessfreq-period-container").addEventListener("click",refreshAction),document.getElementById("local-assessfreq-quiz-summary-graph-zoom").addEventListener("click",triggerZoomGraph),document.getElementById("local-assessfreq-quiz-summary-trend-zoom").addEventListener("click",triggerZoomGraph)}})); diff --git a/amd/build/dashboard_quiz.min.js.map b/amd/build/dashboard_quiz.min.js.map index 77a95835..9a8a67a5 100644 --- a/amd/build/dashboard_quiz.min.js.map +++ b/amd/build/dashboard_quiz.min.js.map @@ -1 +1 @@ -{"version":3,"file":"dashboard_quiz.min.js","sources":["../src/dashboard_quiz.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\n/**\n * Javascript for report card display and processing.\n *\n * @module local_assessfreq/dashboard_quiz\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\nimport * as Str from 'core/str';\nimport Templates from 'core/templates';\nimport * as ChartData from 'local_assessfreq/chart_data';\nimport * as FormModal from 'local_assessfreq/form_modal';\nimport OverrideModal from 'local_assessfreq/override_modal';\nimport * as TableHandler from 'local_assessfreq/table_handler';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\nimport * as ZoomModal from 'local_assessfreq/zoom_modal';\n\n// Module level variables.\n\nvar selectQuizStr = '';\nvar contextid;\nvar quizId = 0;\nvar refreshPeriod = 60;\nvar counterid;\n\nconst cards = [\n {cardId: 'local-assessfreq-quiz-summary-graph', call: 'participant_summary', aspect: true},\n {cardId: 'local-assessfreq-quiz-summary-trend', call: 'participant_trend', aspect: false}\n];\n\n/**\n * Function for refreshing the counter.\n *\n * @param {boolean} reset the current count process.\n */\nconst refreshCounter = (reset = true) => {\n let progressElement = document.getElementById('local-assessfreq-period-progress');\n\n // Reset the current count process.\n if (reset === true) {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n }\n\n // Exit early if there is already a counter running.\n if (counterid) {\n return;\n }\n\n counterid = setInterval(() => {\n let progressWidthAria = progressElement.getAttribute('aria-valuenow');\n const progressStep = 100 / refreshPeriod;\n\n if ((progressWidthAria - progressStep) > 0) {\n progressElement.setAttribute('style', 'width: ' + (progressWidthAria - progressStep) + '%');\n progressElement.setAttribute('aria-valuenow', (progressWidthAria - progressStep));\n } else {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n processDashboard(quizId);\n refreshCounter();\n }\n }, (1000));\n};\n\n/**\n * Callback function that is called when a quiz is selected from the form.\n * Starts the processing of the dashboard.\n *\n * @param {int} quiz The quiz Id.\n */\nconst processDashboard = (quiz) => {\n quizId = quiz;\n let titleElement = document.getElementById('local-assessfreq-quiz-title');\n titleElement.innerHTML = selectQuizStr;\n // Get quiz data.\n Ajax.call([{\n methodname: 'local_assessfreq_get_quiz_data',\n args: {\n quizid: quiz\n },\n }])[0].then((response) => {\n\n let quizArray = JSON.parse(response);\n let cardsElement = document.getElementById('local-assessfreq-quiz-dashboard-cards-deck');\n let trendElement = document.getElementById('local-assessfreq-quiz-dashboard-participant-trend-deck');\n let summaryElement = document.getElementById('local-assessfreq-quiz-summary-card');\n let summarySpinner = summaryElement.getElementsByClassName('overlay-icon-container')[0];\n let tableElement = document.getElementById('local-assessfreq-quiz-table');\n let periodElement = document.getElementById('local-assessfreq-period-container');\n let tableSearchInputElement = document.getElementById('local-assessfreq-quiz-student-table-search');\n let tableSearchResetElement = document.getElementById('local-assessfreq-quiz-student-table-search-reset');\n let tableSearchRowsElement = document.getElementById('local-assessfreq-quiz-student-table-rows');\n\n let quizLink = document.createElement('a');\n quizLink.href = quizArray.url;\n quizLink.innerHTML = '';\n titleElement.innerHTML = quizArray.name + ' ';\n titleElement.appendChild(quizLink);\n\n // Update page URL with quiz ID, without reloading page so that page navigation and bookmarking works.\n const currentdUrl = new URL(window.location.href);\n const newUrl = currentdUrl.origin + currentdUrl.pathname + '?id=' + quizId;\n history.pushState({}, '', newUrl);\n\n // Update page title with quiz name.\n Str.get_string('dashboard:quiztitle', 'local_assessfreq', {'quiz': quizArray.name, 'course': quizArray.courseshortname})\n .then((str) => {\n document.title = str;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: dashboard:quiztitle'));\n });\n\n // Populate quiz summary card with details.\n Templates.render('local_assessfreq/quiz-summary-card-content', quizArray).done((html) => {\n summarySpinner.classList.add('hide');\n let contentcontainer = document.getElementById('local-assessfreq-quiz-summary-card-content');\n Templates.replaceNodeContents(contentcontainer, html, '');\n }).fail(() => {\n Notification.exception(new Error('Failed to load quiz summary template.'));\n return;\n });\n\n // Show the cards.\n cardsElement.classList.remove('hide');\n trendElement.classList.remove('hide');\n tableElement.classList.remove('hide');\n periodElement.classList.remove('hide');\n\n ChartData.getCardCharts(quizId);\n TableHandler.getTable(quizId);\n refreshCounter();\n\n tableSearchInputElement.addEventListener('keyup', TableHandler.tableSearch);\n tableSearchInputElement.addEventListener('paste', TableHandler.tableSearch);\n tableSearchResetElement.addEventListener('click', TableHandler.tableSearchReset);\n tableSearchRowsElement.addEventListener('click', TableHandler.tableSearchRowSet);\n\n return;\n }).fail(() => {\n Notification.exception(new Error('Failed to get quiz data'));\n });\n};\n\n/**\n * Handle processing of refresh and period button actions.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst refreshAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.closest('button') !== null && element.closest('button').id === 'local-assessfreq-refresh-quiz-dashboard') {\n refreshCounter(true);\n processDashboard(quizId);\n } else if (element.tagName.toLowerCase() === 'a') {\n refreshPeriod = element.dataset.period;\n refreshCounter(true);\n UserPreference.setUserPreference('local_assessfreq_quiz_refresh_preference', refreshPeriod);\n }\n};\n\n/**\n * Trigger the zoom graph. Thin wrapper to add extra data to click event.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst triggerZoomGraph = (event) => {\n let call = event.target.closest('div').dataset.call;\n let params = {'data': JSON.stringify({'quiz': quizId, 'call': call})};\n let method = 'get_quiz_chart';\n\n ZoomModal.zoomGraph(event, params, method);\n};\n\n/**\n * Initialise method for quiz dashboard rendering.\n *\n * @param {int} context The context id.\n * @param {int} quiz The quiz id.\n */\nexport const init = (context, quiz) => {\n contextid = context;\n FormModal.init(context, processDashboard); // Create modal for quiz selection modal.\n ZoomModal.init(context); // Create the zoom modal.\n OverrideModal.init(context, processDashboard);\n TableHandler.init(\n quizId,\n contextid,\n 'local-assessfreq-quiz-student-table',\n 'local-assessfreq-quiz-table',\n 'get_student_table',\n 'local_assessfreq_quiz_table_rows_preference',\n 'local-assessfreq-quiz-student-table-search',\n 'local_assessfreq_student_table',\n 'local_assessfreq_set_table_preference'\n );\n ChartData.init(cards, context, 'get_quiz_chart', 'local_assessfreq/chart');\n Str.get_string('loadingquiztitle', 'local_assessfreq').then((str) => {\n selectQuizStr = str;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: loadingquiz'));\n }).then(() => {\n if (quiz > 0) {\n quizId = quiz;\n processDashboard(quiz);\n }\n });\n\n UserPreference.getUserPreference('local_assessfreq_quiz_refresh_preference')\n .then((response) => {\n refreshPeriod = response.preferences[0].value ? response.preferences[0].value : 60;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: refresh'));\n });\n\n // Event handling for refresh and period buttons.\n let refreshElement = document.getElementById('local-assessfreq-period-container');\n refreshElement.addEventListener('click', refreshAction);\n\n // Set up zoom event listeners.\n let summaryZoom = document.getElementById('local-assessfreq-quiz-summary-graph-zoom');\n summaryZoom.addEventListener('click', triggerZoomGraph);\n\n let trendZoom = document.getElementById('local-assessfreq-quiz-summary-trend-zoom');\n trendZoom.addEventListener('click', triggerZoomGraph);\n\n};\n"],"names":["contextid","counterid","selectQuizStr","quizId","refreshPeriod","cards","cardId","call","aspect","refreshCounter","reset","progressElement","document","getElementById","clearInterval","setAttribute","setInterval","progressWidthAria","getAttribute","progressStep","processDashboard","quiz","titleElement","innerHTML","methodname","args","quizid","then","response","quizArray","JSON","parse","cardsElement","trendElement","summarySpinner","getElementsByClassName","tableElement","periodElement","tableSearchInputElement","tableSearchResetElement","tableSearchRowsElement","quizLink","createElement","href","url","name","appendChild","currentdUrl","URL","window","location","newUrl","origin","pathname","history","pushState","Str","get_string","courseshortname","str","title","catch","exception","Error","render","done","html","classList","add","contentcontainer","replaceNodeContents","fail","remove","ChartData","getCardCharts","TableHandler","getTable","addEventListener","tableSearch","tableSearchReset","tableSearchRowSet","refreshAction","event","preventDefault","element","target","closest","id","tagName","toLowerCase","dataset","period","UserPreference","setUserPreference","triggerZoomGraph","params","stringify","ZoomModal","zoomGraph","context","FormModal","init","getUserPreference","preferences","value"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"dashboard_quiz.min.js","sources":["../src/dashboard_quiz.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\n/**\n * Javascript for report card display and processing.\n *\n * @module local_assessfreq/dashboard_quiz\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\nimport * as Str from 'core/str';\nimport Templates from 'core/templates';\nimport * as ChartData from 'local_assessfreq/chart_data';\nimport * as FormModal from 'local_assessfreq/form_modal';\nimport OverrideModal from 'local_assessfreq/override_modal';\nimport * as TableHandler from 'local_assessfreq/table_handler';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\nimport * as ZoomModal from 'local_assessfreq/zoom_modal';\n\n// Module level variables.\n\nvar selectQuizStr = '';\nvar contextid;\nvar quizId = 0;\nvar refreshPeriod = 60;\nvar counterid;\n\nconst cards = [\n {cardId: 'local-assessfreq-quiz-summary-graph', call: 'participant_summary', aspect: true},\n {cardId: 'local-assessfreq-quiz-summary-trend', call: 'participant_trend', aspect: false}\n];\n\n/**\n * Function for refreshing the counter.\n *\n * @param {boolean} reset the current count process.\n */\nconst refreshCounter = (reset = true) => {\n let progressElement = document.getElementById('local-assessfreq-period-progress');\n\n // Reset the current count process.\n if (reset === true) {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n }\n\n // Exit early if there is already a counter running.\n if (counterid) {\n return;\n }\n\n counterid = setInterval(() => {\n let progressWidthAria = progressElement.getAttribute('aria-valuenow');\n const progressStep = 100 / refreshPeriod;\n\n if ((progressWidthAria - progressStep) > 0) {\n progressElement.setAttribute('style', 'width: ' + (progressWidthAria - progressStep) + '%');\n progressElement.setAttribute('aria-valuenow', (progressWidthAria - progressStep));\n } else {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n processDashboard(quizId);\n refreshCounter();\n }\n }, (1000));\n};\n\n/**\n * Callback function that is called when a quiz is selected from the form.\n * Starts the processing of the dashboard.\n *\n * @param {int} quiz The quiz Id.\n */\nconst processDashboard = (quiz) => {\n quizId = quiz;\n let titleElement = document.getElementById('local-assessfreq-quiz-title');\n titleElement.innerHTML = selectQuizStr;\n // Get quiz data.\n Ajax.call([{\n methodname: 'local_assessfreq_get_quiz_data',\n args: {\n quizid: quiz\n },\n }])[0].then((response) => {\n\n let quizArray = JSON.parse(response);\n let cardsElement = document.getElementById('local-assessfreq-quiz-dashboard-cards-deck');\n let trendElement = document.getElementById('local-assessfreq-quiz-dashboard-participant-trend-deck');\n let summaryElement = document.getElementById('local-assessfreq-quiz-summary-card');\n let summarySpinner = summaryElement.getElementsByClassName('overlay-icon-container')[0];\n let tableElement = document.getElementById('local-assessfreq-quiz-table');\n let periodElement = document.getElementById('local-assessfreq-period-container');\n let tableSearchInputElement = document.getElementById('local-assessfreq-quiz-student-table-search');\n let tableSearchResetElement = document.getElementById('local-assessfreq-quiz-student-table-search-reset');\n let tableSearchRowsElement = document.getElementById('local-assessfreq-quiz-student-table-rows');\n\n let quizLink = document.createElement('a');\n quizLink.href = quizArray.url;\n quizLink.innerHTML = '';\n titleElement.innerHTML = quizArray.name + ' ';\n titleElement.appendChild(quizLink);\n\n // Update page URL with quiz ID, without reloading page so that page navigation and bookmarking works.\n const currentdUrl = new URL(window.location.href);\n const newUrl = currentdUrl.origin + currentdUrl.pathname + '?id=' + quizId;\n history.pushState({}, '', newUrl);\n\n // Update page title with quiz name.\n Str.get_string('dashboard:quiztitle', 'local_assessfreq', {'quiz': quizArray.name, 'course': quizArray.courseshortname})\n .then((str) => {\n document.title = str;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: dashboard:quiztitle'));\n });\n\n // Populate quiz summary card with details.\n Templates.render('local_assessfreq/quiz-summary-card-content', quizArray).done((html) => {\n summarySpinner.classList.add('hide');\n let contentcontainer = document.getElementById('local-assessfreq-quiz-summary-card-content');\n Templates.replaceNodeContents(contentcontainer, html, '');\n }).fail(() => {\n Notification.exception(new Error('Failed to load quiz summary template.'));\n return;\n });\n\n // Show the cards.\n cardsElement.classList.remove('hide');\n trendElement.classList.remove('hide');\n tableElement.classList.remove('hide');\n periodElement.classList.remove('hide');\n\n ChartData.getCardCharts(quizId);\n TableHandler.getTable(quizId);\n refreshCounter();\n\n tableSearchInputElement.addEventListener('keyup', TableHandler.tableSearch);\n tableSearchInputElement.addEventListener('paste', TableHandler.tableSearch);\n tableSearchResetElement.addEventListener('click', TableHandler.tableSearchReset);\n tableSearchRowsElement.addEventListener('click', TableHandler.tableSearchRowSet);\n\n return;\n }).fail(() => {\n Notification.exception(new Error('Failed to get quiz data'));\n });\n};\n\n/**\n * Handle processing of refresh and period button actions.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst refreshAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.closest('button') !== null && element.closest('button').id === 'local-assessfreq-refresh-quiz-dashboard') {\n refreshCounter(true);\n processDashboard(quizId);\n } else if (element.tagName.toLowerCase() === 'a') {\n refreshPeriod = element.dataset.period;\n refreshCounter(true);\n UserPreference.setUserPreference('local_assessfreq_quiz_refresh_preference', refreshPeriod);\n }\n};\n\n/**\n * Trigger the zoom graph. Thin wrapper to add extra data to click event.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst triggerZoomGraph = (event) => {\n let call = event.target.closest('div').dataset.call;\n let params = {'data': JSON.stringify({'quiz': quizId, 'call': call})};\n let method = 'get_quiz_chart';\n\n ZoomModal.zoomGraph(event, params, method);\n};\n\n/**\n * Initialise method for quiz dashboard rendering.\n *\n * @param {int} context The context id.\n * @param {int} quiz The quiz id.\n */\nexport const init = (context, quiz) => {\n contextid = context;\n FormModal.init(context, processDashboard); // Create modal for quiz selection modal.\n ZoomModal.init(context); // Create the zoom modal.\n OverrideModal.init(context, processDashboard);\n TableHandler.init(\n quizId,\n contextid,\n 'local-assessfreq-quiz-student-table',\n 'local-assessfreq-quiz-table',\n 'get_student_table',\n 'local_assessfreq_quiz_table_rows_preference',\n 'local-assessfreq-quiz-student-table-search',\n 'local_assessfreq_student_table',\n 'local_assessfreq_set_table_preference'\n );\n ChartData.init(cards, context, 'get_quiz_chart', 'local_assessfreq/chart');\n Str.get_string('loadingquiztitle', 'local_assessfreq').then((str) => {\n selectQuizStr = str;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: loadingquiz'));\n }).then(() => {\n if (quiz > 0) {\n quizId = quiz;\n processDashboard(quiz);\n }\n });\n\n UserPreference.getUserPreference('local_assessfreq_quiz_refresh_preference')\n .then((response) => {\n refreshPeriod = response.preferences[0].value ? response.preferences[0].value : 60;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: refresh'));\n });\n\n // Event handling for refresh and period buttons.\n let refreshElement = document.getElementById('local-assessfreq-period-container');\n refreshElement.addEventListener('click', refreshAction);\n\n // Set up zoom event listeners.\n let summaryZoom = document.getElementById('local-assessfreq-quiz-summary-graph-zoom');\n summaryZoom.addEventListener('click', triggerZoomGraph);\n\n let trendZoom = document.getElementById('local-assessfreq-quiz-summary-trend-zoom');\n trendZoom.addEventListener('click', triggerZoomGraph);\n\n};\n"],"names":["contextid","counterid","selectQuizStr","quizId","refreshPeriod","cards","cardId","call","aspect","refreshCounter","reset","progressElement","document","getElementById","clearInterval","setAttribute","setInterval","progressWidthAria","getAttribute","progressStep","processDashboard","quiz","titleElement","innerHTML","methodname","args","quizid","then","response","quizArray","JSON","parse","cardsElement","trendElement","summarySpinner","getElementsByClassName","tableElement","periodElement","tableSearchInputElement","tableSearchResetElement","tableSearchRowsElement","quizLink","createElement","href","url","name","appendChild","currentdUrl","URL","window","location","newUrl","origin","pathname","history","pushState","Str","get_string","courseshortname","str","title","catch","exception","Error","render","done","html","classList","add","contentcontainer","replaceNodeContents","fail","remove","ChartData","getCardCharts","TableHandler","getTable","addEventListener","tableSearch","tableSearchReset","tableSearchRowSet","refreshAction","event","preventDefault","element","target","closest","id","tagName","toLowerCase","dataset","period","UserPreference","setUserPreference","triggerZoomGraph","params","stringify","ZoomModal","zoomGraph","context","FormModal","init","getUserPreference","preferences","value"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/dashboard_quiz_inprogress.min.js b/amd/build/dashboard_quiz_inprogress.min.js index b5e9f3d4..7554495d 100644 --- a/amd/build/dashboard_quiz_inprogress.min.js +++ b/amd/build/dashboard_quiz_inprogress.min.js @@ -3,7 +3,6 @@ define("local_assessfreq/dashboard_quiz_inprogress",["exports","core/ajax","core * Javascript for quizzes in progress display and processing. * * @module local_assessfreq/dashboard_quiz_inprogress - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */var contextid;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_ajax=_interopRequireDefault(_ajax),_notification=_interopRequireDefault(_notification),_templates=_interopRequireDefault(_templates),ChartData=_interopRequireWildcard(ChartData),TableHandler=_interopRequireWildcard(TableHandler),UserPreference=_interopRequireWildcard(UserPreference),ZoomModal=_interopRequireWildcard(ZoomModal);var counterid,hoursFilter,refreshPeriod=60,tablesort="name_asc",hoursAhead=0,hoursBehind=0;const cards=[{cardId:"local-assessfreq-quiz-summary-upcomming-graph",call:"upcomming_quizzes",aspect:!0},{cardId:"local-assessfreq-quiz-summary-inprogress-graph",call:"all_participants_inprogress",aspect:!0}],refreshCounter=function(){let reset=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],progressElement=document.getElementById("local-assessfreq-period-progress");!0===reset&&(clearInterval(counterid),counterid=null,progressElement.setAttribute("style","width: 100%"),progressElement.setAttribute("aria-valuenow",100)),counterid||(counterid=setInterval((()=>{let progressWidthAria=progressElement.getAttribute("aria-valuenow");const progressStep=100/refreshPeriod;progressWidthAria-progressStep>0?(progressElement.setAttribute("style","width: "+(progressWidthAria-progressStep)+"%"),progressElement.setAttribute("aria-valuenow",progressWidthAria-progressStep)):(clearInterval(counterid),counterid=null,progressElement.setAttribute("style","width: 100%"),progressElement.setAttribute("aria-valuenow",100),processDashboard(),refreshCounter())}),1e3))},processDashboard=()=>{_ajax.default.call([{methodname:"local_assessfreq_get_inprogress_counts",args:{}}])[0].then((response=>{let quizSummary=JSON.parse(response),summaryElement=document.getElementById("local-assessfreq-quiz-dashboard-inprogress-summary-card"),summarySpinner=summaryElement.getElementsByClassName("overlay-icon-container")[0],tableSearchInputElement=document.getElementById("local-assessfreq-quiz-inprogress-table-search"),tableSearchResetElement=document.getElementById("local-assessfreq-quiz-inprogress-table-search-reset"),tableSearchRowsElement=document.getElementById("local-assessfreq-quiz-inprogress-table-rows"),tableSortElement=document.getElementById("local-assessfreq-inprogress-table-sort");summaryElement.classList.remove("hide"),_templates.default.render("local_assessfreq/quiz-dashboard-inprogress-summary-card-content",quizSummary).done((html=>{summarySpinner.classList.add("hide");let contentcontainer=document.getElementById("local-assessfreq-quiz-dashboard-inprogress-summary-card-content");_templates.default.replaceNodeContents(contentcontainer,html,"")})).fail((()=>{_notification.default.exception(new Error("Failed to load quiz counts template."))})),hoursFilter=[hoursAhead,hoursBehind],ChartData.getCardCharts(0,hoursFilter),TableHandler.getTable(0,hoursFilter,tablesort),refreshCounter(),tableSearchInputElement.addEventListener("keyup",TableHandler.tableSearch),tableSearchInputElement.addEventListener("paste",TableHandler.tableSearch),tableSearchResetElement.addEventListener("click",TableHandler.tableSearchReset),tableSearchRowsElement.addEventListener("click",TableHandler.tableSearchRowSet),tableSortElement.addEventListener("click",TableHandler.tableSortButtonAction)})).fail((()=>{_notification.default.exception(new Error("Failed to get quiz summary counts"))}))},refreshAction=event=>{event.preventDefault();var element=event.target;null!==element.closest("button")&&"local-assessfreq-refresh-quiz-dashboard"===element.closest("button").id?(refreshCounter(!0),processDashboard()):"a"===element.tagName.toLowerCase()&&(refreshPeriod=element.dataset.period,refreshCounter(!0),UserPreference.setUserPreference("local_assessfreq_quiz_refresh_preference",refreshPeriod))},triggerZoomGraph=event=>{let call=event.target.closest("div").dataset.call,params={data:JSON.stringify({call:call,hoursahead:hoursAhead,hoursbehind:hoursBehind})};ZoomModal.zoomGraph(event,params,"get_quiz_inprogress_chart")},quizzesAheadSet=event=>{if(event.preventDefault(),"a"===event.target.tagName.toLowerCase()){let hours=event.target.dataset.metric;UserPreference.setUserPreference("local_assessfreq_quizzes_inprogress_table_hoursahead_preference",hours).then((()=>{hoursAhead=hours,processDashboard()})).fail((()=>{_notification.default.exception(new Error("Failed to update user preference: hours ahead"))}))}},quizzesBehindSet=event=>{if(event.preventDefault(),"a"===event.target.tagName.toLowerCase()){let hours=event.target.dataset.metric;UserPreference.setUserPreference("local_assessfreq_quizzes_inprogress_table_hoursbehind_preference",hours).then((()=>{hoursBehind=hours,processDashboard()})).fail((()=>{_notification.default.exception(new Error("Failed to update user preference: hours behind"))}))}};_exports.init=context=>{contextid=context,ZoomModal.init(context),TableHandler.init(0,contextid,null,"local-assessfreq-quiz-inprogress-table","get_quizzes_inprogress_table","local_assessfreq_quiz_table_inprogress_preference","local-assessfreq-quiz-inprogress-table-search"),ChartData.init(cards,context,"get_quiz_inprogress_chart","local_assessfreq/chart"),UserPreference.getUserPreference("local_assessfreq_quiz_refresh_preference").then((response=>{refreshPeriod=response.preferences[0].value?response.preferences[0].value:60})).fail((()=>{_notification.default.exception(new Error("Failed to get use preference: refresh"))})),UserPreference.getUserPreference("local_assessfreq_quiz_table_inprogress_sort_preference").then((response=>{tablesort=response.preferences[0].value?response.preferences[0].value:"name_asc"})).fail((()=>{_notification.default.exception(new Error("Failed to get use preference: tablesort"))})),UserPreference.getUserPreference("local_assessfreq_quizzes_inprogress_table_hoursahead_preference").then((response=>{hoursAhead=response.preferences[0].value?response.preferences[0].value:0})).fail((()=>{_notification.default.exception(new Error("Failed to get use preference: hoursahead"))})),UserPreference.getUserPreference("local_assessfreq_quizzes_inprogress_table_hoursbehind_preference").then((response=>{hoursBehind=response.preferences[0].value?response.preferences[0].value:0})).fail((()=>{_notification.default.exception(new Error("Failed to get use preference: hoursbehind"))})),document.getElementById("local-assessfreq-period-container").addEventListener("click",refreshAction),document.getElementById("local-assessfreq-quiz-summary-inprogress-graph-zoom").addEventListener("click",triggerZoomGraph),document.getElementById("local-assessfreq-quiz-summary-upcomming-graph-zoom").addEventListener("click",triggerZoomGraph),document.getElementById("local-assessfreq-quiz-student-table-hoursahead").addEventListener("click",quizzesAheadSet),document.getElementById("local-assessfreq-quiz-student-table-hoursbehind").addEventListener("click",quizzesBehindSet),processDashboard()}})); diff --git a/amd/build/dashboard_quiz_inprogress.min.js.map b/amd/build/dashboard_quiz_inprogress.min.js.map index ca4bf695..c0cf6aa7 100644 --- a/amd/build/dashboard_quiz_inprogress.min.js.map +++ b/amd/build/dashboard_quiz_inprogress.min.js.map @@ -1 +1 @@ -{"version":3,"file":"dashboard_quiz_inprogress.min.js","sources":["../src/dashboard_quiz_inprogress.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\n/**\n * Javascript for quizzes in progress display and processing.\n *\n * @module local_assessfreq/dashboard_quiz_inprogress\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport * as ChartData from 'local_assessfreq/chart_data';\nimport * as TableHandler from 'local_assessfreq/table_handler';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\nimport * as ZoomModal from 'local_assessfreq/zoom_modal';\n\n/**\n * Module level variables.\n */\nvar contextid;\nvar refreshPeriod = 60;\nvar counterid;\nvar tablesort = 'name_asc';\nvar hoursAhead = 0;\nvar hoursBehind = 0;\n\n/**\n * Hours filter array.\n *\n * @type {array} Title to display on modal.\n */\nvar hoursFilter;\n\nconst cards = [\n {cardId: 'local-assessfreq-quiz-summary-upcomming-graph', call: 'upcomming_quizzes', aspect: true},\n {cardId: 'local-assessfreq-quiz-summary-inprogress-graph', call: 'all_participants_inprogress', aspect: true}\n];\n\n/**\n * Function for refreshing the counter.\n *\n * @param {boolean} reset the current count process.\n */\nconst refreshCounter = (reset = true) => {\n let progressElement = document.getElementById('local-assessfreq-period-progress');\n\n // Reset the current count process.\n if (reset === true) {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n }\n\n // Exit early if there is already a counter running.\n if (counterid) {\n return;\n }\n\n counterid = setInterval(() => {\n let progressWidthAria = progressElement.getAttribute('aria-valuenow');\n const progressStep = 100 / refreshPeriod;\n\n if ((progressWidthAria - progressStep) > 0) {\n progressElement.setAttribute('style', 'width: ' + (progressWidthAria - progressStep) + '%');\n progressElement.setAttribute('aria-valuenow', (progressWidthAria - progressStep));\n } else {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n processDashboard();\n refreshCounter();\n }\n }, (1000));\n};\n\n/**\n * Starts the processing of the dashboard.\n */\nconst processDashboard = () => {\n // Get summary quiz data.\n Ajax.call([{\n methodname: 'local_assessfreq_get_inprogress_counts',\n args: {},\n }])[0].then((response) => {\n let quizSummary = JSON.parse(response);\n let summaryElement = document.getElementById('local-assessfreq-quiz-dashboard-inprogress-summary-card');\n let summarySpinner = summaryElement.getElementsByClassName('overlay-icon-container')[0];\n let tableSearchInputElement = document.getElementById('local-assessfreq-quiz-inprogress-table-search');\n let tableSearchResetElement = document.getElementById('local-assessfreq-quiz-inprogress-table-search-reset');\n let tableSearchRowsElement = document.getElementById('local-assessfreq-quiz-inprogress-table-rows');\n let tableSortElement = document.getElementById('local-assessfreq-inprogress-table-sort');\n\n summaryElement.classList.remove('hide'); // Show the card.\n\n // Populate summary card with details.\n Templates.render('local_assessfreq/quiz-dashboard-inprogress-summary-card-content', quizSummary)\n .done((html) => {\n summarySpinner.classList.add('hide');\n\n let contentcontainer = document.getElementById('local-assessfreq-quiz-dashboard-inprogress-summary-card-content');\n Templates.replaceNodeContents(contentcontainer, html, '');\n }).fail(() => {\n Notification.exception(new Error('Failed to load quiz counts template.'));\n return;\n });\n\n hoursFilter = [hoursAhead, hoursBehind];\n ChartData.getCardCharts(0, hoursFilter);\n TableHandler.getTable(0, hoursFilter, tablesort);\n refreshCounter();\n\n // Table event listeners.\n tableSearchInputElement.addEventListener('keyup', TableHandler.tableSearch);\n tableSearchInputElement.addEventListener('paste', TableHandler.tableSearch);\n tableSearchResetElement.addEventListener('click', TableHandler.tableSearchReset);\n tableSearchRowsElement.addEventListener('click', TableHandler.tableSearchRowSet);\n tableSortElement.addEventListener('click', TableHandler.tableSortButtonAction);\n\n return;\n }).fail(() => {\n Notification.exception(new Error('Failed to get quiz summary counts'));\n });\n};\n\n/**\n * Handle processing of refresh and period button actions.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst refreshAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.closest('button') !== null && element.closest('button').id === 'local-assessfreq-refresh-quiz-dashboard') {\n refreshCounter(true);\n processDashboard();\n } else if (element.tagName.toLowerCase() === 'a') {\n refreshPeriod = element.dataset.period;\n refreshCounter(true);\n UserPreference.setUserPreference('local_assessfreq_quiz_refresh_preference', refreshPeriod);\n }\n};\n\n/**\n * Trigger the zoom graph. Thin wrapper to add extra data to click event.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst triggerZoomGraph = (event) => {\n let call = event.target.closest('div').dataset.call;\n let params = {'data': JSON.stringify({'call': call, 'hoursahead': hoursAhead, 'hoursbehind': hoursBehind})};\n let method = 'get_quiz_inprogress_chart';\n\n ZoomModal.zoomGraph(event, params, method);\n};\n\n/**\n * Process the hours ahead event from the in progress quizzes table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst quizzesAheadSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let hours = event.target.dataset.metric;\n UserPreference.setUserPreference('local_assessfreq_quizzes_inprogress_table_hoursahead_preference', hours)\n .then(() => {\n hoursAhead = hours;\n processDashboard(); // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: hours ahead'));\n });\n }\n};\n\n/**\n * Process the hours behind event from the in progress quizzes table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst quizzesBehindSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let hours = event.target.dataset.metric;\n UserPreference.setUserPreference('local_assessfreq_quizzes_inprogress_table_hoursbehind_preference', hours)\n .then(() => {\n hoursBehind = hours;\n processDashboard(); // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: hours behind'));\n });\n }\n};\n\n/**\n * Initialise method for quizzes in progress dashboard rendering.\n *\n * @param {int} context The context id.\n */\nexport const init = (context) => {\n contextid = context;\n ZoomModal.init(context); // Create the zoom modal.\n TableHandler.init(\n 0,\n contextid,\n null,\n 'local-assessfreq-quiz-inprogress-table',\n 'get_quizzes_inprogress_table',\n 'local_assessfreq_quiz_table_inprogress_preference',\n 'local-assessfreq-quiz-inprogress-table-search'\n );\n ChartData.init(cards, context, 'get_quiz_inprogress_chart', 'local_assessfreq/chart');\n\n UserPreference.getUserPreference('local_assessfreq_quiz_refresh_preference')\n .then((response) => {\n refreshPeriod = response.preferences[0].value ? response.preferences[0].value : 60;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: refresh'));\n });\n\n UserPreference.getUserPreference('local_assessfreq_quiz_table_inprogress_sort_preference')\n .then((response) => {\n tablesort = response.preferences[0].value ? response.preferences[0].value : 'name_asc';\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: tablesort'));\n });\n\n UserPreference.getUserPreference('local_assessfreq_quizzes_inprogress_table_hoursahead_preference')\n .then((response) => {\n hoursAhead = response.preferences[0].value ? response.preferences[0].value : 0;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: hoursahead'));\n });\n\n UserPreference.getUserPreference('local_assessfreq_quizzes_inprogress_table_hoursbehind_preference')\n .then((response) => {\n hoursBehind = response.preferences[0].value ? response.preferences[0].value : 0;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: hoursbehind'));\n });\n\n // Event handling for refresh and period buttons.\n let refreshElement = document.getElementById('local-assessfreq-period-container');\n refreshElement.addEventListener('click', refreshAction);\n\n // Set up zoom event listeners.\n let summaryZoom = document.getElementById('local-assessfreq-quiz-summary-inprogress-graph-zoom');\n summaryZoom.addEventListener('click', triggerZoomGraph);\n\n let upcommingZoom = document.getElementById('local-assessfreq-quiz-summary-upcomming-graph-zoom');\n upcommingZoom.addEventListener('click', triggerZoomGraph);\n\n // Set up behind and ahead quizzes event listeners.\n let quizzesAheadElement = document.getElementById('local-assessfreq-quiz-student-table-hoursahead');\n quizzesAheadElement.addEventListener('click', quizzesAheadSet);\n\n let quizzesBehindElement = document.getElementById('local-assessfreq-quiz-student-table-hoursbehind');\n quizzesBehindElement.addEventListener('click', quizzesBehindSet);\n\n processDashboard();\n\n};\n"],"names":["contextid","counterid","hoursFilter","refreshPeriod","tablesort","hoursAhead","hoursBehind","cards","cardId","call","aspect","refreshCounter","reset","progressElement","document","getElementById","clearInterval","setAttribute","setInterval","progressWidthAria","getAttribute","progressStep","processDashboard","methodname","args","then","response","quizSummary","JSON","parse","summaryElement","summarySpinner","getElementsByClassName","tableSearchInputElement","tableSearchResetElement","tableSearchRowsElement","tableSortElement","classList","remove","render","done","html","add","contentcontainer","replaceNodeContents","fail","exception","Error","ChartData","getCardCharts","TableHandler","getTable","addEventListener","tableSearch","tableSearchReset","tableSearchRowSet","tableSortButtonAction","refreshAction","event","preventDefault","element","target","closest","id","tagName","toLowerCase","dataset","period","UserPreference","setUserPreference","triggerZoomGraph","params","stringify","ZoomModal","zoomGraph","quizzesAheadSet","hours","metric","quizzesBehindSet","context","init","getUserPreference","preferences","value"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"dashboard_quiz_inprogress.min.js","sources":["../src/dashboard_quiz_inprogress.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\n/**\n * Javascript for quizzes in progress display and processing.\n *\n * @module local_assessfreq/dashboard_quiz_inprogress\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport * as ChartData from 'local_assessfreq/chart_data';\nimport * as TableHandler from 'local_assessfreq/table_handler';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\nimport * as ZoomModal from 'local_assessfreq/zoom_modal';\n\n/**\n * Module level variables.\n */\nvar contextid;\nvar refreshPeriod = 60;\nvar counterid;\nvar tablesort = 'name_asc';\nvar hoursAhead = 0;\nvar hoursBehind = 0;\n\n/**\n * Hours filter array.\n *\n * @type {array} Title to display on modal.\n */\nvar hoursFilter;\n\nconst cards = [\n {cardId: 'local-assessfreq-quiz-summary-upcomming-graph', call: 'upcomming_quizzes', aspect: true},\n {cardId: 'local-assessfreq-quiz-summary-inprogress-graph', call: 'all_participants_inprogress', aspect: true}\n];\n\n/**\n * Function for refreshing the counter.\n *\n * @param {boolean} reset the current count process.\n */\nconst refreshCounter = (reset = true) => {\n let progressElement = document.getElementById('local-assessfreq-period-progress');\n\n // Reset the current count process.\n if (reset === true) {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n }\n\n // Exit early if there is already a counter running.\n if (counterid) {\n return;\n }\n\n counterid = setInterval(() => {\n let progressWidthAria = progressElement.getAttribute('aria-valuenow');\n const progressStep = 100 / refreshPeriod;\n\n if ((progressWidthAria - progressStep) > 0) {\n progressElement.setAttribute('style', 'width: ' + (progressWidthAria - progressStep) + '%');\n progressElement.setAttribute('aria-valuenow', (progressWidthAria - progressStep));\n } else {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n processDashboard();\n refreshCounter();\n }\n }, (1000));\n};\n\n/**\n * Starts the processing of the dashboard.\n */\nconst processDashboard = () => {\n // Get summary quiz data.\n Ajax.call([{\n methodname: 'local_assessfreq_get_inprogress_counts',\n args: {},\n }])[0].then((response) => {\n let quizSummary = JSON.parse(response);\n let summaryElement = document.getElementById('local-assessfreq-quiz-dashboard-inprogress-summary-card');\n let summarySpinner = summaryElement.getElementsByClassName('overlay-icon-container')[0];\n let tableSearchInputElement = document.getElementById('local-assessfreq-quiz-inprogress-table-search');\n let tableSearchResetElement = document.getElementById('local-assessfreq-quiz-inprogress-table-search-reset');\n let tableSearchRowsElement = document.getElementById('local-assessfreq-quiz-inprogress-table-rows');\n let tableSortElement = document.getElementById('local-assessfreq-inprogress-table-sort');\n\n summaryElement.classList.remove('hide'); // Show the card.\n\n // Populate summary card with details.\n Templates.render('local_assessfreq/quiz-dashboard-inprogress-summary-card-content', quizSummary)\n .done((html) => {\n summarySpinner.classList.add('hide');\n\n let contentcontainer = document.getElementById('local-assessfreq-quiz-dashboard-inprogress-summary-card-content');\n Templates.replaceNodeContents(contentcontainer, html, '');\n }).fail(() => {\n Notification.exception(new Error('Failed to load quiz counts template.'));\n return;\n });\n\n hoursFilter = [hoursAhead, hoursBehind];\n ChartData.getCardCharts(0, hoursFilter);\n TableHandler.getTable(0, hoursFilter, tablesort);\n refreshCounter();\n\n // Table event listeners.\n tableSearchInputElement.addEventListener('keyup', TableHandler.tableSearch);\n tableSearchInputElement.addEventListener('paste', TableHandler.tableSearch);\n tableSearchResetElement.addEventListener('click', TableHandler.tableSearchReset);\n tableSearchRowsElement.addEventListener('click', TableHandler.tableSearchRowSet);\n tableSortElement.addEventListener('click', TableHandler.tableSortButtonAction);\n\n return;\n }).fail(() => {\n Notification.exception(new Error('Failed to get quiz summary counts'));\n });\n};\n\n/**\n * Handle processing of refresh and period button actions.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst refreshAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.closest('button') !== null && element.closest('button').id === 'local-assessfreq-refresh-quiz-dashboard') {\n refreshCounter(true);\n processDashboard();\n } else if (element.tagName.toLowerCase() === 'a') {\n refreshPeriod = element.dataset.period;\n refreshCounter(true);\n UserPreference.setUserPreference('local_assessfreq_quiz_refresh_preference', refreshPeriod);\n }\n};\n\n/**\n * Trigger the zoom graph. Thin wrapper to add extra data to click event.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst triggerZoomGraph = (event) => {\n let call = event.target.closest('div').dataset.call;\n let params = {'data': JSON.stringify({'call': call, 'hoursahead': hoursAhead, 'hoursbehind': hoursBehind})};\n let method = 'get_quiz_inprogress_chart';\n\n ZoomModal.zoomGraph(event, params, method);\n};\n\n/**\n * Process the hours ahead event from the in progress quizzes table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst quizzesAheadSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let hours = event.target.dataset.metric;\n UserPreference.setUserPreference('local_assessfreq_quizzes_inprogress_table_hoursahead_preference', hours)\n .then(() => {\n hoursAhead = hours;\n processDashboard(); // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: hours ahead'));\n });\n }\n};\n\n/**\n * Process the hours behind event from the in progress quizzes table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst quizzesBehindSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let hours = event.target.dataset.metric;\n UserPreference.setUserPreference('local_assessfreq_quizzes_inprogress_table_hoursbehind_preference', hours)\n .then(() => {\n hoursBehind = hours;\n processDashboard(); // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: hours behind'));\n });\n }\n};\n\n/**\n * Initialise method for quizzes in progress dashboard rendering.\n *\n * @param {int} context The context id.\n */\nexport const init = (context) => {\n contextid = context;\n ZoomModal.init(context); // Create the zoom modal.\n TableHandler.init(\n 0,\n contextid,\n null,\n 'local-assessfreq-quiz-inprogress-table',\n 'get_quizzes_inprogress_table',\n 'local_assessfreq_quiz_table_inprogress_preference',\n 'local-assessfreq-quiz-inprogress-table-search'\n );\n ChartData.init(cards, context, 'get_quiz_inprogress_chart', 'local_assessfreq/chart');\n\n UserPreference.getUserPreference('local_assessfreq_quiz_refresh_preference')\n .then((response) => {\n refreshPeriod = response.preferences[0].value ? response.preferences[0].value : 60;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: refresh'));\n });\n\n UserPreference.getUserPreference('local_assessfreq_quiz_table_inprogress_sort_preference')\n .then((response) => {\n tablesort = response.preferences[0].value ? response.preferences[0].value : 'name_asc';\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: tablesort'));\n });\n\n UserPreference.getUserPreference('local_assessfreq_quizzes_inprogress_table_hoursahead_preference')\n .then((response) => {\n hoursAhead = response.preferences[0].value ? response.preferences[0].value : 0;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: hoursahead'));\n });\n\n UserPreference.getUserPreference('local_assessfreq_quizzes_inprogress_table_hoursbehind_preference')\n .then((response) => {\n hoursBehind = response.preferences[0].value ? response.preferences[0].value : 0;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: hoursbehind'));\n });\n\n // Event handling for refresh and period buttons.\n let refreshElement = document.getElementById('local-assessfreq-period-container');\n refreshElement.addEventListener('click', refreshAction);\n\n // Set up zoom event listeners.\n let summaryZoom = document.getElementById('local-assessfreq-quiz-summary-inprogress-graph-zoom');\n summaryZoom.addEventListener('click', triggerZoomGraph);\n\n let upcommingZoom = document.getElementById('local-assessfreq-quiz-summary-upcomming-graph-zoom');\n upcommingZoom.addEventListener('click', triggerZoomGraph);\n\n // Set up behind and ahead quizzes event listeners.\n let quizzesAheadElement = document.getElementById('local-assessfreq-quiz-student-table-hoursahead');\n quizzesAheadElement.addEventListener('click', quizzesAheadSet);\n\n let quizzesBehindElement = document.getElementById('local-assessfreq-quiz-student-table-hoursbehind');\n quizzesBehindElement.addEventListener('click', quizzesBehindSet);\n\n processDashboard();\n\n};\n"],"names":["contextid","counterid","hoursFilter","refreshPeriod","tablesort","hoursAhead","hoursBehind","cards","cardId","call","aspect","refreshCounter","reset","progressElement","document","getElementById","clearInterval","setAttribute","setInterval","progressWidthAria","getAttribute","progressStep","processDashboard","methodname","args","then","response","quizSummary","JSON","parse","summaryElement","summarySpinner","getElementsByClassName","tableSearchInputElement","tableSearchResetElement","tableSearchRowsElement","tableSortElement","classList","remove","render","done","html","add","contentcontainer","replaceNodeContents","fail","exception","Error","ChartData","getCardCharts","TableHandler","getTable","addEventListener","tableSearch","tableSearchReset","tableSearchRowSet","tableSortButtonAction","refreshAction","event","preventDefault","element","target","closest","id","tagName","toLowerCase","dataset","period","UserPreference","setUserPreference","triggerZoomGraph","params","stringify","ZoomModal","zoomGraph","quizzesAheadSet","hours","metric","quizzesBehindSet","context","init","getUserPreference","preferences","value"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/dayview.min.js b/amd/build/dayview.min.js index 047d5c40..8c7b3f8f 100644 --- a/amd/build/dayview.min.js +++ b/amd/build/dayview.min.js @@ -1,7 +1,6 @@ /** * Javascript for heatmap calendar generation and display. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/build/dayview.min.js.map b/amd/build/dayview.min.js.map index ce6bb145..19659d1a 100644 --- a/amd/build/dayview.min.js.map +++ b/amd/build/dayview.min.js.map @@ -1 +1 @@ -{"version":3,"file":"dayview.min.js","sources":["../src/dayview.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\n/**\n * Javascript for heatmap calendar generation and display.\n *\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['core/str', 'core/notification', 'core/modal', 'local_assessfreq/modal_large', 'core/templates', 'core/ajax'],\n function (Str, Notification, Modal, ModalLarge, Templates, Ajax) {\n\n /**\n * Module level variables.\n */\n var Dayview = {};\n var modalObj;\n const spinner = '

'\n + ''\n + '

';\n\n const stringArr = [\n {key: 'sun', component: 'calendar'},\n {key: 'mon', component: 'calendar'},\n {key: 'tue', component: 'calendar'},\n {key: 'wed', component: 'calendar'},\n {key: 'thu', component: 'calendar'},\n {key: 'fri', component: 'calendar'},\n {key: 'sat', component: 'calendar'},\n {key: 'jan', component: 'local_assessfreq'},\n {key: 'feb', component: 'local_assessfreq'},\n {key: 'mar', component: 'local_assessfreq'},\n {key: 'apr', component: 'local_assessfreq'},\n {key: 'may', component: 'local_assessfreq'},\n {key: 'jun', component: 'local_assessfreq'},\n {key: 'jul', component: 'local_assessfreq'},\n {key: 'aug', component: 'local_assessfreq'},\n {key: 'sep', component: 'local_assessfreq'},\n {key: 'oct', component: 'local_assessfreq'},\n {key: 'nov', component: 'local_assessfreq'},\n {key: 'dec', component: 'local_assessfreq'},\n ];\n var stringResult;\n var systemTimezone = 'Australia/Melbourne';\n var dayViewTitle = '';\n\n const getUserDate = function (timestamp, format) {\n return new Promise((resolve) => {\n const systemTimezoneTime = new Date(timestamp * 1000).toLocaleString('en-US', {timeZone: systemTimezone});\n let date = new Date(systemTimezoneTime);\n const year = date.getFullYear();\n const month = stringResult[(7 + date.getMonth())];\n const day = date.getDate();\n const hours = date.getHours();\n const minutes = '0' + date.getMinutes();\n\n const strftimetime = hours + ':' + minutes.substr(-2); // Will display time in 10:30 format.\n const strftimedatetime = day + ' ' + month + ' ' + year + ', ' + strftimetime;\n\n if (format === 'strftimetime') {\n resolve(strftimetime);\n } else {\n resolve(strftimedatetime);\n }\n\n });\n };\n\n const formatData = async function (response) {\n let responseArr = JSON.parse(response);\n\n // We are displaying the event as a bar whose width represents the start and end time of the event.\n // We need to scale the width of the bar to match the width of the container. Therefore 100% width of the container\n // equals 24 hours (one day).\n // There are 1440 mins per day. 1440 mins equals 100%, therefore 1 min = (100/1440)%. 5/72 == 100/1440.\n let scaler = 5 / 72;\n\n for (let i = 0; i < responseArr.length; i++) {\n const year = responseArr[i].endyear;\n const month = (responseArr[i].endmonth) - 1; // Minus 1 for difference between months in PHP and JS.\n const day = responseArr[i].endday;\n const dayStart = (new Date(year, month, day).getTime()) / 1000;\n const timeStart = new Date(responseArr[i].timestart * 1000).toLocaleString('en-US', {timeZone: systemTimezone});\n const timeStartTimestamp = (new Date(timeStart).getTime()) / 1000;\n const timeEnd = new Date(responseArr[i].timeend * 1000).toLocaleString('en-US', {timeZone: systemTimezone});\n const timeEndTimestamp = (new Date(timeEnd).getTime()) / 1000;\n let secondsSinceDayStart = timeStartTimestamp - dayStart;\n let leftMargin = 0;\n let width = 0;\n\n if (secondsSinceDayStart <= 0) {\n secondsSinceDayStart = 0;\n width = ((timeEndTimestamp - dayStart) / 60) * scaler;\n responseArr[i].start = await getUserDate(responseArr[i].timestart, 'strftimedatetime');\n } else {\n leftMargin = (secondsSinceDayStart / 60) * scaler;\n width = ((timeEndTimestamp - timeStartTimestamp) / 60) * scaler;\n responseArr[i].start = await getUserDate(responseArr[i].timestart, 'strftimetime');\n }\n\n if (leftMargin + width > 100) {\n width = 100 - leftMargin;\n }\n\n responseArr[i].leftmargin = leftMargin;\n responseArr[i].width = width;\n responseArr[i].end = await getUserDate(responseArr[i].timeend, 'strftimetime');\n }\n\n return new Promise((resolve) => {\n resolve(responseArr);\n });\n };\n\n /**\n * Initialise the base modal to be used.\n *\n */\n Dayview.display = function (date) {\n modalObj.setBody(spinner);\n modalObj.show();\n let args = {\n date: date,\n modules: ['all']\n };\n let jsonArgs = JSON.stringify(args);\n Ajax.call([{\n methodname: 'local_assessfreq_get_day_events',\n args: {jsondata: jsonArgs},\n }])[0]\n .then(formatData)\n .then((responseArr) => {\n\n let context = {rows: responseArr};\n const year = responseArr[0].endyear;\n const day = responseArr[0].endday;\n const month = stringResult[(6 + parseInt(responseArr[0].endmonth))];\n const dayDate = day + ' ' + month + ' ' + year;\n\n modalObj.setTitle(dayViewTitle + ' ' + dayDate);\n modalObj.setBody(Templates.render('local_assessfreq/dayview', context));\n\n }).fail(() => {\n Notification.exception(new Error('Failed to load day view'));\n });\n };\n\n /**\n * Initialise the base modal to be used.\n *\n * @param {integer} context The current context id.\n */\n Dayview.init = function () {\n // Load the strings we'll need later.\n Str.get_strings(stringArr).catch(() => { // Get required strings.\n Notification.exception(new Error('Failed to load strings'));\n return;\n }).then(stringReturn => { // Save string to global to be used later.\n stringResult = stringReturn;\n });\n\n // Get the system timzone.\n Ajax.call([{\n methodname: 'local_assessfreq_get_system_timezone',\n args: {},\n }], true, false)[0].then((response) => {\n systemTimezone = response;\n return;\n }).fail(() => {\n Notification.exception(new Error('Failed to get system timezone'));\n });\n\n Str.get_string('schedule', 'local_assessfreq').then((title) => {\n dayViewTitle = title;\n\n // Create the Modal.\n Modal.create({\n type: ModalLarge.TYPE,\n title: title,\n body: spinner,\n large: true\n })\n .then((modal) => {\n modalObj = modal;\n\n });\n }).catch(Notification.exception);\n\n };\n\n return Dayview;\n }\n);\n"],"names":["define","Str","Notification","Modal","ModalLarge","Templates","Ajax","modalObj","Dayview","spinner","stringArr","key","component","stringResult","systemTimezone","dayViewTitle","getUserDate","timestamp","format","Promise","resolve","systemTimezoneTime","Date","toLocaleString","timeZone","date","year","getFullYear","month","getMonth","day","getDate","strftimetime","getHours","getMinutes","substr","formatData","async","response","responseArr","JSON","parse","scaler","i","length","endyear","endmonth","endday","dayStart","getTime","timeStart","timestart","timeStartTimestamp","timeEnd","timeend","timeEndTimestamp","secondsSinceDayStart","leftMargin","width","start","leftmargin","end","display","setBody","show","args","modules","jsonArgs","stringify","call","methodname","jsondata","then","context","rows","dayDate","parseInt","setTitle","render","fail","exception","Error","init","get_strings","catch","stringReturn","get_string","title","create","type","TYPE","body","large","modal"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"dayview.min.js","sources":["../src/dayview.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\n/**\n * Javascript for heatmap calendar generation and display.\n *\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['core/str', 'core/notification', 'core/modal', 'local_assessfreq/modal_large', 'core/templates', 'core/ajax'],\n function (Str, Notification, Modal, ModalLarge, Templates, Ajax) {\n\n /**\n * Module level variables.\n */\n var Dayview = {};\n var modalObj;\n const spinner = '

'\n + ''\n + '

';\n\n const stringArr = [\n {key: 'sun', component: 'calendar'},\n {key: 'mon', component: 'calendar'},\n {key: 'tue', component: 'calendar'},\n {key: 'wed', component: 'calendar'},\n {key: 'thu', component: 'calendar'},\n {key: 'fri', component: 'calendar'},\n {key: 'sat', component: 'calendar'},\n {key: 'jan', component: 'local_assessfreq'},\n {key: 'feb', component: 'local_assessfreq'},\n {key: 'mar', component: 'local_assessfreq'},\n {key: 'apr', component: 'local_assessfreq'},\n {key: 'may', component: 'local_assessfreq'},\n {key: 'jun', component: 'local_assessfreq'},\n {key: 'jul', component: 'local_assessfreq'},\n {key: 'aug', component: 'local_assessfreq'},\n {key: 'sep', component: 'local_assessfreq'},\n {key: 'oct', component: 'local_assessfreq'},\n {key: 'nov', component: 'local_assessfreq'},\n {key: 'dec', component: 'local_assessfreq'},\n ];\n var stringResult;\n var systemTimezone = 'Australia/Melbourne';\n var dayViewTitle = '';\n\n const getUserDate = function (timestamp, format) {\n return new Promise((resolve) => {\n const systemTimezoneTime = new Date(timestamp * 1000).toLocaleString('en-US', {timeZone: systemTimezone});\n let date = new Date(systemTimezoneTime);\n const year = date.getFullYear();\n const month = stringResult[(7 + date.getMonth())];\n const day = date.getDate();\n const hours = date.getHours();\n const minutes = '0' + date.getMinutes();\n\n const strftimetime = hours + ':' + minutes.substr(-2); // Will display time in 10:30 format.\n const strftimedatetime = day + ' ' + month + ' ' + year + ', ' + strftimetime;\n\n if (format === 'strftimetime') {\n resolve(strftimetime);\n } else {\n resolve(strftimedatetime);\n }\n\n });\n };\n\n const formatData = async function (response) {\n let responseArr = JSON.parse(response);\n\n // We are displaying the event as a bar whose width represents the start and end time of the event.\n // We need to scale the width of the bar to match the width of the container. Therefore 100% width of the container\n // equals 24 hours (one day).\n // There are 1440 mins per day. 1440 mins equals 100%, therefore 1 min = (100/1440)%. 5/72 == 100/1440.\n let scaler = 5 / 72;\n\n for (let i = 0; i < responseArr.length; i++) {\n const year = responseArr[i].endyear;\n const month = (responseArr[i].endmonth) - 1; // Minus 1 for difference between months in PHP and JS.\n const day = responseArr[i].endday;\n const dayStart = (new Date(year, month, day).getTime()) / 1000;\n const timeStart = new Date(responseArr[i].timestart * 1000).toLocaleString('en-US', {timeZone: systemTimezone});\n const timeStartTimestamp = (new Date(timeStart).getTime()) / 1000;\n const timeEnd = new Date(responseArr[i].timeend * 1000).toLocaleString('en-US', {timeZone: systemTimezone});\n const timeEndTimestamp = (new Date(timeEnd).getTime()) / 1000;\n let secondsSinceDayStart = timeStartTimestamp - dayStart;\n let leftMargin = 0;\n let width = 0;\n\n if (secondsSinceDayStart <= 0) {\n secondsSinceDayStart = 0;\n width = ((timeEndTimestamp - dayStart) / 60) * scaler;\n responseArr[i].start = await getUserDate(responseArr[i].timestart, 'strftimedatetime');\n } else {\n leftMargin = (secondsSinceDayStart / 60) * scaler;\n width = ((timeEndTimestamp - timeStartTimestamp) / 60) * scaler;\n responseArr[i].start = await getUserDate(responseArr[i].timestart, 'strftimetime');\n }\n\n if (leftMargin + width > 100) {\n width = 100 - leftMargin;\n }\n\n responseArr[i].leftmargin = leftMargin;\n responseArr[i].width = width;\n responseArr[i].end = await getUserDate(responseArr[i].timeend, 'strftimetime');\n }\n\n return new Promise((resolve) => {\n resolve(responseArr);\n });\n };\n\n /**\n * Initialise the base modal to be used.\n *\n * @param {int} date The date to display the day view for.\n *\n */\n Dayview.display = function (date) {\n modalObj.setBody(spinner);\n modalObj.show();\n let args = {\n date: date,\n modules: ['all']\n };\n let jsonArgs = JSON.stringify(args);\n Ajax.call([{\n methodname: 'local_assessfreq_get_day_events',\n args: {jsondata: jsonArgs},\n }])[0]\n .then(formatData)\n .then((responseArr) => {\n\n let context = {rows: responseArr};\n const year = responseArr[0].endyear;\n const day = responseArr[0].endday;\n const month = stringResult[(6 + parseInt(responseArr[0].endmonth))];\n const dayDate = day + ' ' + month + ' ' + year;\n\n modalObj.setTitle(dayViewTitle + ' ' + dayDate);\n modalObj.setBody(Templates.render('local_assessfreq/dayview', context));\n\n }).fail(() => {\n Notification.exception(new Error('Failed to load day view'));\n });\n };\n\n /**\n * Initialise the base modal to be used.\n *\n */\n Dayview.init = function () {\n // Load the strings we'll need later.\n Str.get_strings(stringArr).catch(() => { // Get required strings.\n Notification.exception(new Error('Failed to load strings'));\n return;\n }).then(stringReturn => { // Save string to global to be used later.\n stringResult = stringReturn;\n });\n\n // Get the system timzone.\n Ajax.call([{\n methodname: 'local_assessfreq_get_system_timezone',\n args: {},\n }], true, false)[0].then((response) => {\n systemTimezone = response;\n return;\n }).fail(() => {\n Notification.exception(new Error('Failed to get system timezone'));\n });\n\n Str.get_string('schedule', 'local_assessfreq').then((title) => {\n dayViewTitle = title;\n\n // Create the Modal.\n Modal.create({\n type: ModalLarge.TYPE,\n title: title,\n body: spinner,\n large: true\n })\n .then((modal) => {\n modalObj = modal;\n\n });\n }).catch(Notification.exception);\n\n };\n\n return Dayview;\n }\n);\n"],"names":["define","Str","Notification","Modal","ModalLarge","Templates","Ajax","modalObj","Dayview","spinner","stringArr","key","component","stringResult","systemTimezone","dayViewTitle","getUserDate","timestamp","format","Promise","resolve","systemTimezoneTime","Date","toLocaleString","timeZone","date","year","getFullYear","month","getMonth","day","getDate","strftimetime","getHours","getMinutes","substr","formatData","async","response","responseArr","JSON","parse","scaler","i","length","endyear","endmonth","endday","dayStart","getTime","timeStart","timestart","timeStartTimestamp","timeEnd","timeend","timeEndTimestamp","secondsSinceDayStart","leftMargin","width","start","leftmargin","end","display","setBody","show","args","modules","jsonArgs","stringify","call","methodname","jsondata","then","context","rows","dayDate","parseInt","setTitle","render","fail","exception","Error","init","get_strings","catch","stringReturn","get_string","title","create","type","TYPE","body","large","modal"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/debouncer.min.js.map b/amd/build/debouncer.min.js.map index 9479d9c5..d989c5ea 100644 --- a/amd/build/debouncer.min.js.map +++ b/amd/build/debouncer.min.js.map @@ -1 +1 @@ -{"version":3,"file":"debouncer.min.js","sources":["../src/debouncer.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\n/**\n * Debounce JS module.\n *\n * @module local_assessfreq/debouncer\n * @package local_assessfreq\n * @copyright 2020 Guillermo Gomez \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n/**\n * Quick and dirty debounce method for the settings.\n * This stops the ajax method that updates the table from being updated\n * while the user is still checking options.\n *\n * @method debouncer\n * @param {function} func The function we want to keep calling.\n * @param {number} wait Our timeout.\n * @return {function}\n */\nexport const debouncer = (func, wait) => {\n let timeout;\n\n return function executedFunction(...args) {\n const later = () => {\n clearTimeout(timeout);\n func(...args);\n };\n\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n};\n"],"names":["func","wait","timeout","args","later","clearTimeout","setTimeout"],"mappings":"yKAmCyB,CAACA,KAAMC,YACxBC,eAEG,yCAA6BC,6CAAAA,iCAC1BC,MAAQ,KACVC,aAAaH,SACbF,QAAQG,OAGZE,aAAaH,SACbA,QAAUI,WAAWF,MAAOH"} \ No newline at end of file +{"version":3,"file":"debouncer.min.js","sources":["../src/debouncer.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\n/**\n * Debounce JS module.\n *\n * @module local_assessfreq/debouncer\n * @copyright 2020 Guillermo Gomez \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n/**\n * Quick and dirty debounce method for the settings.\n * This stops the ajax method that updates the table from being updated\n * while the user is still checking options.\n *\n * @method debouncer\n * @param {function} func The function we want to keep calling.\n * @param {number} wait Our timeout.\n * @return {function}\n */\nexport const debouncer = (func, wait) => {\n let timeout;\n\n return function executedFunction(...args) {\n const later = () => {\n clearTimeout(timeout);\n func(...args);\n };\n\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n};\n"],"names":["func","wait","timeout","args","later","clearTimeout","setTimeout"],"mappings":"yKAkCyB,CAACA,KAAMC,YACxBC,eAEG,yCAA6BC,6CAAAA,iCAC1BC,MAAQ,KACVC,aAAaH,SACbF,QAAQG,OAGZE,aAAaH,SACbA,QAAUI,WAAWF,MAAOH"} \ No newline at end of file diff --git a/amd/build/form_modal.min.js b/amd/build/form_modal.min.js index 971b71f9..6a7baee2 100644 --- a/amd/build/form_modal.min.js +++ b/amd/build/form_modal.min.js @@ -1,10 +1,9 @@ /** * Javascript for report card display and processing. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("local_assessfreq/form_modal",["core/str","core/modal","core/fragment","core/ajax"],(function(Str,Modal,Fragment,Ajax){var contextid,modalObj,callback,FormModal={},resetOptions=[];const spinner='

',observerConfig={attributes:!0,childList:!1,subtree:!0},observer=new MutationObserver((function(mutationsList){for(let i=0;i{let quizArray=JSON.parse(response),selectElement=document.getElementById("id_quiz"),selectElementLength=selectElement.options.length;null!==document.getElementById("noquizwarning")&&document.getElementById("noquizwarning").remove();for(let j=selectElementLength-1;j>=0;j--)selectElement.options[j]=null;if(quizArray.length>0){for(let k=0;k{selectElement.appendChild(option)})),document.getElementById("id_quiz").value=0,selectElement.disabled=!0})).fail((()=>{Notification.exception(new Error("Failed to get quizzes"))}));break}}})),updateModalBody=function(formdata){void 0===formdata&&(formdata={});let params={jsonformdata:JSON.stringify(formdata)};new Promise(((resolve,reject)=>{Str.get_strings([{key:"selectcourse",component:"local_assessfreq"},{key:"loadingquiz",component:"local_assessfreq"}]).catch((()=>{reject(new Error("Failed to load strings"))})).then((stringReturn=>{for(let i=0;i{Str.get_string("searchquiz","local_assessfreq").then((title=>{modalObj.setTitle(title),modalObj.setBody(Fragment.loadFragment("local_assessfreq","new_base_form",contextid,params));let modalContainer=document.querySelectorAll('[data-region*="modal-container"]')[0];observer.observe(modalContainer,observerConfig)})).catch((()=>{Notification.exception(new Error("Failed to load string: searchquiz"))}))}))},processModalForm=function(e){e.preventDefault();let quizElement=document.getElementById("id_quiz"),quizId=quizElement.options[quizElement.selectedIndex].value,courseId=document.getElementById("id_courses").dataset.course;void 0===courseId||quizId<1?null===document.getElementById("noquizwarning")&&Str.get_string("noquizselected","local_assessfreq").then((warning=>{let element=document.createElement("div");element.innerHTML=warning,element.id="noquizwarning",element.classList.add("alert","alert-danger"),modalObj.getBody().prepend(element)})).catch((()=>{Notification.exception(new Error("Failed to load string: searchquiz"))})):(modalObj.hide(),modalObj.setBody(""),observer.disconnect(),callback(quizId,courseId))},displayModalForm=function(){updateModalBody(),modalObj.show()};return FormModal.init=function(context,processDashboard){contextid=context,callback=processDashboard,Str.get_string("loading","local_assessfreq").then((title=>{Modal.create({type:Modal.types.DEFAULT,title:title,body:spinner,large:!0}).then((modal=>{(modalObj=modal).getRoot().on("click","#id_submitbutton",processModalForm),modalObj.getRoot().on("click","#id_cancel",(e=>{e.preventDefault(),modalObj.setBody(spinner),modalObj.hide()}))}))})).catch(Notification.exception),document.getElementById("local-assessfreq-find-quiz").addEventListener("click",displayModalForm)},FormModal})); +define("local_assessfreq/form_modal",["core/str","core/modal","core/fragment","core/ajax","core/notification"],(function(Str,Modal,Fragment,Ajax,Notification){var contextid,modalObj,callback,FormModal={},resetOptions=[];const spinner='

',observerConfig={attributes:!0,childList:!1,subtree:!0},observer=new MutationObserver((function(mutationsList){for(let i=0;i{let quizArray=JSON.parse(response),selectElement=document.getElementById("id_quiz"),selectElementLength=selectElement.options.length;null!==document.getElementById("noquizwarning")&&document.getElementById("noquizwarning").remove();for(let j=selectElementLength-1;j>=0;j--)selectElement.options[j]=null;if(quizArray.length>0){for(let k=0;k{selectElement.appendChild(option)})),document.getElementById("id_quiz").value=0,selectElement.disabled=!0})).fail((()=>{Notification.exception(new Error("Failed to get quizzes"))}));break}}})),updateModalBody=function(formdata){void 0===formdata&&(formdata={});let params={jsonformdata:JSON.stringify(formdata)};new Promise(((resolve,reject)=>{Str.get_strings([{key:"selectcourse",component:"local_assessfreq"},{key:"loadingquiz",component:"local_assessfreq"}]).catch((()=>{reject(new Error("Failed to load strings"))})).then((stringReturn=>{for(let i=0;i{Str.get_string("searchquiz","local_assessfreq").then((title=>{modalObj.setTitle(title),modalObj.setBody(Fragment.loadFragment("local_assessfreq","new_base_form",contextid,params));let modalContainer=document.querySelectorAll('[data-region*="modal-container"]')[0];observer.observe(modalContainer,observerConfig)})).catch((()=>{Notification.exception(new Error("Failed to load string: searchquiz"))}))}))},processModalForm=function(e){e.preventDefault();let quizElement=document.getElementById("id_quiz"),quizId=quizElement.options[quizElement.selectedIndex].value,courseId=document.getElementById("id_courses").dataset.course;void 0===courseId||quizId<1?null===document.getElementById("noquizwarning")&&Str.get_string("noquizselected","local_assessfreq").then((warning=>{let element=document.createElement("div");element.innerHTML=warning,element.id="noquizwarning",element.classList.add("alert","alert-danger"),modalObj.getBody().prepend(element)})).catch((()=>{Notification.exception(new Error("Failed to load string: searchquiz"))})):(modalObj.hide(),modalObj.setBody(""),observer.disconnect(),callback(quizId,courseId))},displayModalForm=function(){updateModalBody(),modalObj.show()};return FormModal.init=function(context,processDashboard){contextid=context,callback=processDashboard,Str.get_string("loading","local_assessfreq").then((title=>{Modal.create({type:Modal.types.DEFAULT,title:title,body:spinner,large:!0}).then((modal=>{(modalObj=modal).getRoot().on("click","#id_submitbutton",processModalForm),modalObj.getRoot().on("click","#id_cancel",(e=>{e.preventDefault(),modalObj.setBody(spinner),modalObj.hide()}))}))})).catch(Notification.exception),document.getElementById("local-assessfreq-find-quiz").addEventListener("click",displayModalForm)},FormModal})); //# sourceMappingURL=form_modal.min.js.map \ No newline at end of file diff --git a/amd/build/form_modal.min.js.map b/amd/build/form_modal.min.js.map index 5bbc35bc..8501197b 100644 --- a/amd/build/form_modal.min.js.map +++ b/amd/build/form_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"form_modal.min.js","sources":["../src/form_modal.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\n/**\n * Javascript for report card display and processing.\n *\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['core/str', 'core/modal', 'core/fragment', 'core/ajax'],\n function (Str, Modal, Fragment, Ajax) {\n\n /**\n * Module level variables.\n */\n var FormModal = {};\n var contextid;\n var modalObj;\n var resetOptions = [];\n var callback;\n\n const spinner = '

'\n + ''\n + '

';\n\n const observerConfig = { attributes: true, childList: false, subtree: true };\n\n const ObserverCallback = function (mutationsList) {\n for (let i = 0; i < mutationsList.length; i++) {\n let element = mutationsList[i].target;\n if (element.tagName.toLowerCase() === 'span' && element.classList.contains('badge')) {\n element.addEventListener('click', updateModalBody);\n document.getElementById('id_courses').dataset.course = element.dataset.value;\n\n document.getElementById('id_quiz').value = -1;\n Ajax.call([{\n methodname: 'local_assessfreq_get_quizzes',\n args: {\n query: mutationsList[i].target.dataset.value\n },\n }])[0].done((response) => {\n let quizArray = JSON.parse(response);\n let selectElement = document.getElementById('id_quiz');\n let selectElementLength = selectElement.options.length;\n if (document.getElementById('noquizwarning') !== null) {\n document.getElementById('noquizwarning').remove();\n }\n // Clear exisitng options.\n for (let j = selectElementLength - 1; j >= 0; j--) {\n selectElement.options[j] = null;\n }\n\n if (quizArray.length > 0) {\n // Add new options.\n for (let k = 0; k < quizArray.length; k++) {\n let opt = quizArray[k];\n let el = document.createElement('option');\n el.textContent = opt.name;\n el.value = opt.id;\n selectElement.appendChild(el);\n }\n selectElement.removeAttribute('disabled');\n if (document.getElementById('noquizwarning') !== null) {\n document.getElementById('noquizwarning').remove();\n }\n } else {\n resetOptions.forEach((option) => {\n selectElement.appendChild(option);\n });\n document.getElementById('id_quiz').value = 0;\n selectElement.disabled = true;\n }\n\n }).fail(() => {\n Notification.exception(new Error('Failed to get quizzes'));\n });\n\n break;\n }\n }\n };\n\n const observer = new MutationObserver(ObserverCallback);\n\n /**\n * Create the modal window.\n *\n * @private\n */\n const createModal = function () {\n Str.get_string('loading', 'local_assessfreq').then((title) => {\n // Create the Modal.\n Modal.create({\n type: Modal.types.DEFAULT,\n title: title,\n body: spinner,\n large: true\n })\n .then((modal) => {\n modalObj = modal;\n\n // Explicitly handle form click events.\n modalObj.getRoot().on('click', '#id_submitbutton', processModalForm);\n modalObj.getRoot().on('click', '#id_cancel', (e) => {\n e.preventDefault();\n modalObj.setBody(spinner);\n modalObj.hide();\n });\n });\n return;\n }).catch(Notification.exception);\n };\n\n const getOptionPlaceholders = function () {\n return new Promise((resolve, reject) => {\n const stringArr = [\n {key: 'selectcourse', component: 'local_assessfreq'},\n {key: 'loadingquiz', component: 'local_assessfreq'},\n ];\n\n Str.get_strings(stringArr).catch(() => { // Get required strings.\n reject(new Error('Failed to load strings'));\n return;\n }).then(stringReturn => { // Save string to global to be used later.\n for (let i = 0; i < stringReturn.length; i++) {\n let el = document.createElement('option');\n el.textContent = stringReturn[i];\n el.value = 0 - i;\n resetOptions.push(el);\n }\n resolve();\n });\n });\n };\n\n /**\n * Updates the body of the modal window.\n *\n * @param {Object} formdata\n * @private\n */\n const updateModalBody = function (formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n\n let params = {\n 'jsonformdata': JSON.stringify(formdata)\n };\n\n getOptionPlaceholders()\n .then(() => {\n Str.get_string('searchquiz', 'local_assessfreq').then((title) => {\n modalObj.setTitle(title);\n modalObj.setBody(Fragment.loadFragment('local_assessfreq', 'new_base_form', contextid, params));\n let modalContainer = document.querySelectorAll('[data-region*=\"modal-container\"]')[0];\n observer.observe(modalContainer, observerConfig);\n\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: searchquiz'));\n });\n });\n };\n\n /**\n * Updates Moodle form with selected information.\n *\n * @param {Object} e\n * @private\n */\n const processModalForm = function (e) {\n e.preventDefault(); // Stop modal from closing.\n\n let quizElement = document.getElementById('id_quiz');\n let quizId = quizElement.options[quizElement.selectedIndex].value;\n let courseId = document.getElementById('id_courses').dataset.course;\n\n if (courseId === undefined || quizId < 1) {\n if (document.getElementById('noquizwarning') === null) {\n Str.get_string('noquizselected', 'local_assessfreq').then((warning) => {\n let element = document.createElement('div');\n element.innerHTML = warning;\n element.id = 'noquizwarning';\n element.classList.add('alert', 'alert-danger');\n modalObj.getBody().prepend(element);\n\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: searchquiz'));\n });\n }\n } else {\n modalObj.hide(); // Close modal.\n modalObj.setBody(''); // Cleaer form.\n observer.disconnect(); // Remove observer.\n callback(quizId, courseId); // Trigger dashboard update.\n }\n\n };\n\n /**\n * Display the Modal form.\n */\n const displayModalForm = function () {\n updateModalBody();\n modalObj.show();\n };\n\n /**\n * Initialise method for quiz dashboard rendering.\n */\n FormModal.init = function (context, processDashboard) {\n contextid = context;\n callback = processDashboard;\n createModal();\n\n let createBroadcastButton = document.getElementById('local-assessfreq-find-quiz');\n createBroadcastButton.addEventListener('click', displayModalForm);\n };\n\n return FormModal;\n }\n);\n"],"names":["define","Str","Modal","Fragment","Ajax","contextid","modalObj","callback","FormModal","resetOptions","spinner","observerConfig","attributes","childList","subtree","observer","MutationObserver","mutationsList","i","length","element","target","tagName","toLowerCase","classList","contains","addEventListener","updateModalBody","document","getElementById","dataset","course","value","call","methodname","args","query","done","response","quizArray","JSON","parse","selectElement","selectElementLength","options","remove","j","k","opt","el","createElement","textContent","name","id","appendChild","removeAttribute","forEach","option","disabled","fail","Notification","exception","Error","formdata","params","stringify","Promise","resolve","reject","get_strings","key","component","catch","then","stringReturn","push","get_string","title","setTitle","setBody","loadFragment","modalContainer","querySelectorAll","observe","processModalForm","e","preventDefault","quizElement","quizId","selectedIndex","courseId","undefined","warning","innerHTML","add","getBody","prepend","hide","disconnect","displayModalForm","show","init","context","processDashboard","create","type","types","DEFAULT","body","large","modal","getRoot","on"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"form_modal.min.js","sources":["../src/form_modal.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\n/**\n * Javascript for report card display and processing.\n *\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['core/str', 'core/modal', 'core/fragment', 'core/ajax', 'core/notification'],\n function (Str, Modal, Fragment, Ajax, Notification) {\n\n /**\n * Module level variables.\n */\n var FormModal = {};\n var contextid;\n var modalObj;\n var resetOptions = [];\n var callback;\n\n const spinner = '

'\n + ''\n + '

';\n\n const observerConfig = { attributes: true, childList: false, subtree: true };\n\n const ObserverCallback = function (mutationsList) {\n for (let i = 0; i < mutationsList.length; i++) {\n let element = mutationsList[i].target;\n if (element.tagName.toLowerCase() === 'span' && element.classList.contains('badge')) {\n element.addEventListener('click', updateModalBody);\n document.getElementById('id_courses').dataset.course = element.dataset.value;\n\n document.getElementById('id_quiz').value = -1;\n Ajax.call([{\n methodname: 'local_assessfreq_get_quizzes',\n args: {\n query: mutationsList[i].target.dataset.value\n },\n }])[0].done((response) => {\n let quizArray = JSON.parse(response);\n let selectElement = document.getElementById('id_quiz');\n let selectElementLength = selectElement.options.length;\n if (document.getElementById('noquizwarning') !== null) {\n document.getElementById('noquizwarning').remove();\n }\n // Clear exisitng options.\n for (let j = selectElementLength - 1; j >= 0; j--) {\n selectElement.options[j] = null;\n }\n\n if (quizArray.length > 0) {\n // Add new options.\n for (let k = 0; k < quizArray.length; k++) {\n let opt = quizArray[k];\n let el = document.createElement('option');\n el.textContent = opt.name;\n el.value = opt.id;\n selectElement.appendChild(el);\n }\n selectElement.removeAttribute('disabled');\n if (document.getElementById('noquizwarning') !== null) {\n document.getElementById('noquizwarning').remove();\n }\n } else {\n resetOptions.forEach((option) => {\n selectElement.appendChild(option);\n });\n document.getElementById('id_quiz').value = 0;\n selectElement.disabled = true;\n }\n\n }).fail(() => {\n Notification.exception(new Error('Failed to get quizzes'));\n });\n\n break;\n }\n }\n };\n\n const observer = new MutationObserver(ObserverCallback);\n\n /**\n * Create the modal window.\n *\n * @private\n */\n const createModal = function () {\n Str.get_string('loading', 'local_assessfreq').then((title) => {\n // Create the Modal.\n Modal.create({\n type: Modal.types.DEFAULT,\n title: title,\n body: spinner,\n large: true\n })\n .then((modal) => {\n modalObj = modal;\n\n // Explicitly handle form click events.\n modalObj.getRoot().on('click', '#id_submitbutton', processModalForm);\n modalObj.getRoot().on('click', '#id_cancel', (e) => {\n e.preventDefault();\n modalObj.setBody(spinner);\n modalObj.hide();\n });\n });\n return;\n }).catch(Notification.exception);\n };\n\n const getOptionPlaceholders = function () {\n return new Promise((resolve, reject) => {\n const stringArr = [\n {key: 'selectcourse', component: 'local_assessfreq'},\n {key: 'loadingquiz', component: 'local_assessfreq'},\n ];\n\n Str.get_strings(stringArr).catch(() => { // Get required strings.\n reject(new Error('Failed to load strings'));\n return;\n }).then(stringReturn => { // Save string to global to be used later.\n for (let i = 0; i < stringReturn.length; i++) {\n let el = document.createElement('option');\n el.textContent = stringReturn[i];\n el.value = 0 - i;\n resetOptions.push(el);\n }\n resolve();\n });\n });\n };\n\n /**\n * Updates the body of the modal window.\n *\n * @param {Object} formdata\n * @private\n */\n const updateModalBody = function (formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n\n let params = {\n 'jsonformdata': JSON.stringify(formdata)\n };\n\n getOptionPlaceholders()\n .then(() => {\n Str.get_string('searchquiz', 'local_assessfreq').then((title) => {\n modalObj.setTitle(title);\n modalObj.setBody(Fragment.loadFragment('local_assessfreq', 'new_base_form', contextid, params));\n let modalContainer = document.querySelectorAll('[data-region*=\"modal-container\"]')[0];\n observer.observe(modalContainer, observerConfig);\n\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: searchquiz'));\n });\n });\n };\n\n /**\n * Updates Moodle form with selected information.\n *\n * @param {Object} e\n * @private\n */\n const processModalForm = function (e) {\n e.preventDefault(); // Stop modal from closing.\n\n let quizElement = document.getElementById('id_quiz');\n let quizId = quizElement.options[quizElement.selectedIndex].value;\n let courseId = document.getElementById('id_courses').dataset.course;\n\n if (courseId === undefined || quizId < 1) {\n if (document.getElementById('noquizwarning') === null) {\n Str.get_string('noquizselected', 'local_assessfreq').then((warning) => {\n let element = document.createElement('div');\n element.innerHTML = warning;\n element.id = 'noquizwarning';\n element.classList.add('alert', 'alert-danger');\n modalObj.getBody().prepend(element);\n\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: searchquiz'));\n });\n }\n } else {\n modalObj.hide(); // Close modal.\n modalObj.setBody(''); // Cleaer form.\n observer.disconnect(); // Remove observer.\n callback(quizId, courseId); // Trigger dashboard update.\n }\n\n };\n\n /**\n * Display the Modal form.\n */\n const displayModalForm = function () {\n updateModalBody();\n modalObj.show();\n };\n\n /**\n * Initialise method for quiz dashboard rendering.\n *\n * @param {int} context The context id for the dashboard.\n * @param {function} processDashboard The callback function to process the dashboard.\n *\n */\n FormModal.init = function (context, processDashboard) {\n contextid = context;\n callback = processDashboard;\n createModal();\n\n let createBroadcastButton = document.getElementById('local-assessfreq-find-quiz');\n createBroadcastButton.addEventListener('click', displayModalForm);\n };\n\n return FormModal;\n }\n);\n"],"names":["define","Str","Modal","Fragment","Ajax","Notification","contextid","modalObj","callback","FormModal","resetOptions","spinner","observerConfig","attributes","childList","subtree","observer","MutationObserver","mutationsList","i","length","element","target","tagName","toLowerCase","classList","contains","addEventListener","updateModalBody","document","getElementById","dataset","course","value","call","methodname","args","query","done","response","quizArray","JSON","parse","selectElement","selectElementLength","options","remove","j","k","opt","el","createElement","textContent","name","id","appendChild","removeAttribute","forEach","option","disabled","fail","exception","Error","formdata","params","stringify","Promise","resolve","reject","get_strings","key","component","catch","then","stringReturn","push","get_string","title","setTitle","setBody","loadFragment","modalContainer","querySelectorAll","observe","processModalForm","e","preventDefault","quizElement","quizId","selectedIndex","courseId","undefined","warning","innerHTML","add","getBody","prepend","hide","disconnect","displayModalForm","show","init","context","processDashboard","create","type","types","DEFAULT","body","large","modal","getRoot","on"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/modal_large.min.js b/amd/build/modal_large.min.js index b8eb94ec..0a4d9a2c 100644 --- a/amd/build/modal_large.min.js +++ b/amd/build/modal_large.min.js @@ -1,7 +1,6 @@ /** * Javascript for large modal . * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/build/modal_large.min.js.map b/amd/build/modal_large.min.js.map index cc525a10..a0e2851c 100644 --- a/amd/build/modal_large.min.js.map +++ b/amd/build/modal_large.min.js.map @@ -1 +1 @@ -{"version":3,"file":"modal_large.min.js","sources":["../src/modal_large.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\n/**\n * Javascript for large modal .\n *\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['jquery', 'core/notification', 'core/custom_interaction_events', 'core/modal', 'core/modal_registry'],\n function ($, Notification, CustomEvents, Modal, ModalRegistry) {\n\n var registered = false;\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n var ModalLarge = function (root) {\n Modal.call(this, root);\n };\n\n ModalLarge.TYPE = 'local_assesfreq-large_modal';\n ModalLarge.prototype = Object.create(Modal.prototype);\n ModalLarge.prototype.constructor = ModalLarge;\n\n /**\n * Set up all of the event handling for the modal.\n *\n * @method registerEventListeners\n */\n ModalLarge.prototype.registerEventListeners = function () {\n // Apply parent event listeners.\n Modal.prototype.registerEventListeners.call(this);\n };\n\n // Automatically register with the modal registry the first time this module is imported so that you can create modals\n // of this type using the modal factory.\n if (!registered) {\n ModalRegistry.register(ModalLarge.TYPE, ModalLarge, 'local_assessfreq/modal_large');\n registered = true;\n }\n\n return ModalLarge;\n }\n);\n"],"names":["define","$","Notification","CustomEvents","Modal","ModalRegistry","registered","ModalLarge","root","call","this","TYPE","prototype","Object","create","constructor","registerEventListeners","register"],"mappings":";;;;;;;AAuBAA,sCACI,CAAC,SAAU,oBAAqB,iCAAkC,aAAc,wBAChF,SAAUC,EAAGC,aAAcC,aAAcC,MAAOC,mBAExCC,YAAa,EAObC,WAAa,SAAUC,MACvBJ,MAAMK,KAAKC,KAAMF,cAGrBD,WAAWI,KAAO,+BAClBJ,WAAWK,UAAYC,OAAOC,OAAOV,MAAMQ,YACtBG,YAAcR,WAOnCA,WAAWK,UAAUI,uBAAyB,WAE1CZ,MAAMQ,UAAUI,uBAAuBP,KAAKC,OAK3CJ,aACDD,cAAcY,SAASV,WAAWI,KAAMJ,WAAY,gCACpDD,YAAa,GAGVC"} \ No newline at end of file +{"version":3,"file":"modal_large.min.js","sources":["../src/modal_large.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\n/**\n * Javascript for large modal .\n *\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['jquery', 'core/notification', 'core/custom_interaction_events', 'core/modal', 'core/modal_registry'],\n function ($, Notification, CustomEvents, Modal, ModalRegistry) {\n\n var registered = false;\n\n /**\n * Constructor for the Modal.\n *\n * @param {object} root The root jQuery element for the modal\n */\n var ModalLarge = function (root) {\n Modal.call(this, root);\n };\n\n ModalLarge.TYPE = 'local_assesfreq-large_modal';\n ModalLarge.prototype = Object.create(Modal.prototype);\n ModalLarge.prototype.constructor = ModalLarge;\n\n /**\n * Set up all of the event handling for the modal.\n *\n * @method registerEventListeners\n */\n ModalLarge.prototype.registerEventListeners = function () {\n // Apply parent event listeners.\n Modal.prototype.registerEventListeners.call(this);\n };\n\n // Automatically register with the modal registry the first time this module is imported so that you can create modals\n // of this type using the modal factory.\n if (!registered) {\n ModalRegistry.register(ModalLarge.TYPE, ModalLarge, 'local_assessfreq/modal_large');\n registered = true;\n }\n\n return ModalLarge;\n }\n);\n"],"names":["define","$","Notification","CustomEvents","Modal","ModalRegistry","registered","ModalLarge","root","call","this","TYPE","prototype","Object","create","constructor","registerEventListeners","register"],"mappings":";;;;;;AAsBAA,sCACI,CAAC,SAAU,oBAAqB,iCAAkC,aAAc,wBAChF,SAAUC,EAAGC,aAAcC,aAAcC,MAAOC,mBAExCC,YAAa,EAObC,WAAa,SAAUC,MACvBJ,MAAMK,KAAKC,KAAMF,cAGrBD,WAAWI,KAAO,+BAClBJ,WAAWK,UAAYC,OAAOC,OAAOV,MAAMQ,YACtBG,YAAcR,WAOnCA,WAAWK,UAAUI,uBAAyB,WAE1CZ,MAAMQ,UAAUI,uBAAuBP,KAAKC,OAK3CJ,aACDD,cAAcY,SAASV,WAAWI,KAAMJ,WAAY,gCACpDD,YAAa,GAGVC"} \ No newline at end of file diff --git a/amd/build/override_modal.min.js b/amd/build/override_modal.min.js index 2a154ec1..5f571ae4 100644 --- a/amd/build/override_modal.min.js +++ b/amd/build/override_modal.min.js @@ -1,10 +1,9 @@ /** * Javascript for report card display and processing. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("local_assessfreq/override_modal",["jquery","core/str","core/modal_factory","core/modal_events","core/fragment","core/ajax"],(function($,Str,Modal,ModalEvents,Fragment,Ajax){var contextid,modalObj,callback,quizid,userid,hoursFilter,OverrideModal={};const spinner='

',createModal=function(){Str.get_string("loading","local_assessfreq").then((title=>{Modal.create({type:Modal.types.DEFAULT,title:title,body:spinner,large:!0}).then((modal=>{(modalObj=modal).getRoot().on("click","#id_submitbutton",processModalForm),modalObj.getRoot().on("click","#id_cancel",(function(e){e.preventDefault(),modalObj.setBody(spinner),modalObj.hide()}))}))})).catch((()=>{Notification.exception(new Error("Failed to load string: loading"))}))},updateModalBody=function(quiz,user,formdata){void 0===formdata&&(formdata={});let params={jsonformdata:JSON.stringify(formdata),quizid:quiz,userid:user};modalObj.setBody(spinner),Str.get_string("useroverride","local_assessfreq").then((title=>{modalObj.setTitle(title),modalObj.setBody(Fragment.loadFragment("local_assessfreq","new_override_form",contextid,params))})).catch((()=>{Notification.exception(new Error("Failed to load string: useroverride"))}))};function processModalForm(e){e.preventDefault();let overrideform=modalObj.getRoot().find("form").serialize(),formjson=JSON.stringify(overrideform);var invalid=$.merge(modalObj.getRoot().find('[aria-invalid="true"]'),modalObj.getRoot().find(".error"));invalid.length?invalid.first().focus():Ajax.call([{methodname:"local_assessfreq_process_override_form",args:{jsonformdata:formjson,quizid:quizid}}])[0].done((()=>{modalObj.setBody(spinner),modalObj.hide(),hoursFilter?callback(quizid,hoursFilter):callback(quizid)})).fail((()=>{updateModalBody(quizid,userid,overrideform)}))}return OverrideModal.displayModalForm=function(quiz,user){let hours=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;quizid=quiz,userid=user,hoursFilter=hours,updateModalBody(quiz,user),modalObj.show()},OverrideModal.init=function(context,callbackFunction){let hours=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;contextid=context,callback=callbackFunction,hoursFilter=hours,createModal()},OverrideModal})); +define("local_assessfreq/override_modal",["jquery","core/str","core/modal_factory","core/modal_events","core/fragment","core/ajax","core/notification"],(function($,Str,Modal,ModalEvents,Fragment,Ajax,Notification){var contextid,modalObj,callback,quizid,userid,hoursFilter,OverrideModal={};const spinner='

',createModal=function(){Str.get_string("loading","local_assessfreq").then((title=>{Modal.create({type:Modal.types.DEFAULT,title:title,body:spinner,large:!0}).then((modal=>{(modalObj=modal).getRoot().on("click","#id_submitbutton",processModalForm),modalObj.getRoot().on("click","#id_cancel",(function(e){e.preventDefault(),modalObj.setBody(spinner),modalObj.hide()}))}))})).catch((()=>{Notification.exception(new Error("Failed to load string: loading"))}))},updateModalBody=function(quiz,user,formdata){void 0===formdata&&(formdata={});let params={jsonformdata:JSON.stringify(formdata),quizid:quiz,userid:user};modalObj.setBody(spinner),Str.get_string("useroverride","local_assessfreq").then((title=>{modalObj.setTitle(title),modalObj.setBody(Fragment.loadFragment("local_assessfreq","new_override_form",contextid,params))})).catch((()=>{Notification.exception(new Error("Failed to load string: useroverride"))}))};function processModalForm(e){e.preventDefault();let overrideform=modalObj.getRoot().find("form").serialize(),formjson=JSON.stringify(overrideform);var invalid=$.merge(modalObj.getRoot().find('[aria-invalid="true"]'),modalObj.getRoot().find(".error"));invalid.length?invalid.first().focus():Ajax.call([{methodname:"local_assessfreq_process_override_form",args:{jsonformdata:formjson,quizid:quizid}}])[0].done((()=>{modalObj.setBody(spinner),modalObj.hide(),hoursFilter?callback(quizid,hoursFilter):callback(quizid)})).fail((()=>{updateModalBody(quizid,userid,overrideform)}))}return OverrideModal.displayModalForm=function(quiz,user){let hours=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;quizid=quiz,userid=user,hoursFilter=hours,updateModalBody(quiz,user),modalObj.show()},OverrideModal.init=function(context,callbackFunction){let hours=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;contextid=context,callback=callbackFunction,hoursFilter=hours,createModal()},OverrideModal})); //# sourceMappingURL=override_modal.min.js.map \ No newline at end of file diff --git a/amd/build/override_modal.min.js.map b/amd/build/override_modal.min.js.map index ebb1ed70..3352be45 100644 --- a/amd/build/override_modal.min.js.map +++ b/amd/build/override_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"override_modal.min.js","sources":["../src/override_modal.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\n/**\n * Javascript for report card display and processing.\n *\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/fragment', 'core/ajax'],\n function ($,Str, Modal, ModalEvents, Fragment, Ajax) {\n\n /**\n * Module level variables.\n */\n var OverrideModal = {};\n var contextid;\n var modalObj;\n var callback;\n var quizid;\n var userid;\n var hoursFilter;\n\n const spinner = '

'\n + ''\n + '

';\n\n /**\n * Create the modal window.\n *\n * @private\n */\n const createModal = function () {\n Str.get_string('loading', 'local_assessfreq').then((title) => {\n // Create the Modal.\n Modal.create({\n type: Modal.types.DEFAULT,\n title: title,\n body: spinner,\n large: true\n })\n .then((modal) => {\n modalObj = modal;\n // Explicitly handle form click events.\n modalObj.getRoot().on('click', '#id_submitbutton', processModalForm);\n modalObj.getRoot().on('click', '#id_cancel', function (e) {\n e.preventDefault();\n modalObj.setBody(spinner);\n modalObj.hide();\n });\n });\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: loading'));\n });\n };\n\n /**\n * Updates the body of the modal window.\n *\n * @param {Object} formdata\n * @private\n */\n const updateModalBody = function (quiz, user, formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n\n let params = {\n 'jsonformdata': JSON.stringify(formdata),\n 'quizid': quiz,\n 'userid': user\n };\n\n modalObj.setBody(spinner);\n Str.get_string('useroverride', 'local_assessfreq').then((title) => {\n modalObj.setTitle(title);\n modalObj.setBody(Fragment.loadFragment('local_assessfreq', 'new_override_form', contextid, params));\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: useroverride'));\n });\n };\n\n /**\n * Updates Moodle form with selected information.\n *\n * @param {Object} e\n * @private\n */\n function processModalForm(e) {\n e.preventDefault(); // Stop modal from closing.\n\n // Form data.\n let overrideform = modalObj.getRoot().find('form').serialize();\n let formjson = JSON.stringify(overrideform);\n\n // Handle invalid form fields for better UX.\n // I hate that I had to use JQuery for this.\n var invalid = $.merge(\n modalObj.getRoot().find('[aria-invalid=\"true\"]'),\n modalObj.getRoot().find('.error')\n );\n\n if (invalid.length) {\n invalid.first().focus();\n return;\n }\n\n // Submit form via ajax.\n Ajax.call([{\n methodname: 'local_assessfreq_process_override_form',\n args: {\n 'jsonformdata': formjson,\n 'quizid': quizid\n },\n }])[0].done(() => {\n // For submission succeeded.\n modalObj.setBody(spinner);\n modalObj.hide();\n if (hoursFilter) {\n callback(quizid, hoursFilter);\n } else {\n callback(quizid);\n }\n }).fail(() => {\n // Form submission failed server side, redisplay with errors.\n updateModalBody(quizid, userid, overrideform);\n });\n }\n\n /**\n * Display the Modal form.\n */\n OverrideModal.displayModalForm = function (quiz, user, hours = null) {\n quizid = quiz;\n userid = user;\n hoursFilter = hours;\n updateModalBody(quiz, user);\n modalObj.show();\n };\n\n /**\n * Initialise method for quiz dashboard rendering.\n */\n OverrideModal.init = function (context, callbackFunction, hours = null) {\n contextid = context;\n callback = callbackFunction;\n hoursFilter = hours;\n createModal();\n };\n\n return OverrideModal;\n }\n);\n"],"names":["define","$","Str","Modal","ModalEvents","Fragment","Ajax","contextid","modalObj","callback","quizid","userid","hoursFilter","OverrideModal","spinner","createModal","get_string","then","title","create","type","types","DEFAULT","body","large","modal","getRoot","on","processModalForm","e","preventDefault","setBody","hide","catch","Notification","exception","Error","updateModalBody","quiz","user","formdata","params","JSON","stringify","setTitle","loadFragment","overrideform","find","serialize","formjson","invalid","merge","length","first","focus","call","methodname","args","done","fail","displayModalForm","hours","show","init","context","callbackFunction"],"mappings":";;;;;;;AAuBAA,yCACI,CAAC,SAAU,WAAY,qBAAsB,oBAAqB,gBAAiB,cACnF,SAAUC,EAAEC,IAAKC,MAAOC,YAAaC,SAAUC,UAMvCC,UACAC,SACAC,SACAC,OACAC,OACAC,YANAC,cAAgB,SAQdC,QAAU,sFASVC,YAAc,WAChBb,IAAIc,WAAW,UAAW,oBAAoBC,MAAMC,QAEhDf,MAAMgB,OAAO,CACTC,KAAMjB,MAAMkB,MAAMC,QAClBJ,MAAOA,MACPK,KAAMT,QACNU,OAAO,IAEVP,MAAMQ,SACHjB,SAAWiB,OAEFC,UAAUC,GAAG,QAAS,mBAAoBC,kBACnDpB,SAASkB,UAAUC,GAAG,QAAS,cAAc,SAAUE,GACnDA,EAAEC,iBACFtB,SAASuB,QAAQjB,SACjBN,SAASwB,gBAIlBC,OAAM,KACLC,aAAaC,UAAU,IAAIC,MAAM,uCAUnCC,gBAAkB,SAAUC,KAAMC,KAAMC,eAClB,IAAbA,WACPA,SAAW,QAGXC,OAAS,cACOC,KAAKC,UAAUH,iBACrBF,YACAC,MAGd/B,SAASuB,QAAQjB,SACjBZ,IAAIc,WAAW,eAAgB,oBAAoBC,MAAMC,QACrDV,SAASoC,SAAS1B,OAClBV,SAASuB,QAAQ1B,SAASwC,aAAa,mBAAoB,oBAAqBtC,UAAWkC,YAE5FR,OAAM,KACLC,aAAaC,UAAU,IAAIC,MAAM,qDAUhCR,iBAAiBC,GACtBA,EAAEC,qBAGEgB,aAAetC,SAASkB,UAAUqB,KAAK,QAAQC,YAC/CC,SAAWP,KAAKC,UAAUG,kBAI1BI,QAAUjD,EAAEkD,MACZ3C,SAASkB,UAAUqB,KAAK,yBACxBvC,SAASkB,UAAUqB,KAAK,WAGxBG,QAAQE,OACRF,QAAQG,QAAQC,QAKpBhD,KAAKiD,KAAK,CAAC,CACPC,WAAY,yCACZC,KAAM,cACcR,gBACNvC,WAEd,GAAGgD,MAAK,KAERlD,SAASuB,QAAQjB,SACjBN,SAASwB,OACLpB,YACAH,SAASC,OAAQE,aAEjBH,SAASC,WAEdiD,MAAK,KAEJtB,gBAAgB3B,OAAQC,OAAQmC,wBAOxCjC,cAAc+C,iBAAmB,SAAUtB,KAAMC,UAAMsB,6DAAQ,KAC3DnD,OAAS4B,KACT3B,OAAS4B,KACT3B,YAAciD,MACdxB,gBAAgBC,KAAMC,MACtB/B,SAASsD,QAMbjD,cAAckD,KAAO,SAAUC,QAASC,sBAAkBJ,6DAAQ,KAC9DtD,UAAYyD,QACZvD,SAAWwD,iBACXrD,YAAciD,MACd9C,eAGGF"} \ No newline at end of file +{"version":3,"file":"override_modal.min.js","sources":["../src/override_modal.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\n/**\n * Javascript for report card display and processing.\n *\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/fragment', 'core/ajax', 'core/notification'],\n function ($,Str, Modal, ModalEvents, Fragment, Ajax, Notification) {\n\n /**\n * Module level variables.\n */\n var OverrideModal = {};\n var contextid;\n var modalObj;\n var callback;\n var quizid;\n var userid;\n var hoursFilter;\n\n const spinner = '

'\n + ''\n + '

';\n\n /**\n * Create the modal window.\n *\n * @private\n */\n const createModal = function () {\n Str.get_string('loading', 'local_assessfreq').then((title) => {\n // Create the Modal.\n Modal.create({\n type: Modal.types.DEFAULT,\n title: title,\n body: spinner,\n large: true\n })\n .then((modal) => {\n modalObj = modal;\n // Explicitly handle form click events.\n modalObj.getRoot().on('click', '#id_submitbutton', processModalForm);\n modalObj.getRoot().on('click', '#id_cancel', function (e) {\n e.preventDefault();\n modalObj.setBody(spinner);\n modalObj.hide();\n });\n });\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: loading'));\n });\n };\n\n /**\n * Updates the body of the modal window.\n *\n * @param {int} quiz The quiz id.\n * @param {int} user The user id.\n * @param {object} formdata The form data.\n */\n const updateModalBody = function (quiz, user, formdata) {\n if (typeof formdata === \"undefined\") {\n formdata = {};\n }\n\n let params = {\n 'jsonformdata': JSON.stringify(formdata),\n 'quizid': quiz,\n 'userid': user\n };\n\n modalObj.setBody(spinner);\n Str.get_string('useroverride', 'local_assessfreq').then((title) => {\n modalObj.setTitle(title);\n modalObj.setBody(Fragment.loadFragment('local_assessfreq', 'new_override_form', contextid, params));\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: useroverride'));\n });\n };\n\n /**\n * Updates Moodle form with selected information.\n *\n * @param {Object} e\n * @private\n */\n function processModalForm(e) {\n e.preventDefault(); // Stop modal from closing.\n\n // Form data.\n let overrideform = modalObj.getRoot().find('form').serialize();\n let formjson = JSON.stringify(overrideform);\n\n // Handle invalid form fields for better UX.\n // I hate that I had to use JQuery for this.\n var invalid = $.merge(\n modalObj.getRoot().find('[aria-invalid=\"true\"]'),\n modalObj.getRoot().find('.error')\n );\n\n if (invalid.length) {\n invalid.first().focus();\n return;\n }\n\n // Submit form via ajax.\n Ajax.call([{\n methodname: 'local_assessfreq_process_override_form',\n args: {\n 'jsonformdata': formjson,\n 'quizid': quizid\n },\n }])[0].done(() => {\n // For submission succeeded.\n modalObj.setBody(spinner);\n modalObj.hide();\n if (hoursFilter) {\n callback(quizid, hoursFilter);\n } else {\n callback(quizid);\n }\n }).fail(() => {\n // Form submission failed server side, redisplay with errors.\n updateModalBody(quizid, userid, overrideform);\n });\n }\n\n /**\n * Display the Modal form.\n *\n * @param {int} quiz The quiz id.\n * @param {int} user The user id.\n * @param {int} hours The hours to filter the quiz by.\n */\n OverrideModal.displayModalForm = function (quiz, user, hours = null) {\n quizid = quiz;\n userid = user;\n hoursFilter = hours;\n updateModalBody(quiz, user);\n modalObj.show();\n };\n\n /**\n * Initialise method for quiz dashboard rendering.\n *\n * @param {int} context The context id for the dashboard.\n * @param {function} callbackFunction The callback function to call after the modal is closed.\n * @param {int} hours The hours to filter the quiz by.\n */\n OverrideModal.init = function (context, callbackFunction, hours = null) {\n contextid = context;\n callback = callbackFunction;\n hoursFilter = hours;\n createModal();\n };\n\n return OverrideModal;\n }\n);\n"],"names":["define","$","Str","Modal","ModalEvents","Fragment","Ajax","Notification","contextid","modalObj","callback","quizid","userid","hoursFilter","OverrideModal","spinner","createModal","get_string","then","title","create","type","types","DEFAULT","body","large","modal","getRoot","on","processModalForm","e","preventDefault","setBody","hide","catch","exception","Error","updateModalBody","quiz","user","formdata","params","JSON","stringify","setTitle","loadFragment","overrideform","find","serialize","formjson","invalid","merge","length","first","focus","call","methodname","args","done","fail","displayModalForm","hours","show","init","context","callbackFunction"],"mappings":";;;;;;AAsBAA,yCACI,CAAC,SAAU,WAAY,qBAAsB,oBAAqB,gBAAiB,YAAa,sBAChG,SAAUC,EAAEC,IAAKC,MAAOC,YAAaC,SAAUC,KAAMC,kBAM7CC,UACAC,SACAC,SACAC,OACAC,OACAC,YANAC,cAAgB,SAQdC,QAAU,sFASVC,YAAc,WAChBd,IAAIe,WAAW,UAAW,oBAAoBC,MAAMC,QAEhDhB,MAAMiB,OAAO,CACTC,KAAMlB,MAAMmB,MAAMC,QAClBJ,MAAOA,MACPK,KAAMT,QACNU,OAAO,IAEVP,MAAMQ,SACHjB,SAAWiB,OAEFC,UAAUC,GAAG,QAAS,mBAAoBC,kBACnDpB,SAASkB,UAAUC,GAAG,QAAS,cAAc,SAAUE,GACnDA,EAAEC,iBACFtB,SAASuB,QAAQjB,SACjBN,SAASwB,gBAIlBC,OAAM,KACL3B,aAAa4B,UAAU,IAAIC,MAAM,uCAWnCC,gBAAkB,SAAUC,KAAMC,KAAMC,eAClB,IAAbA,WACPA,SAAW,QAGXC,OAAS,cACOC,KAAKC,UAAUH,iBACrBF,YACAC,MAGd9B,SAASuB,QAAQjB,SACjBb,IAAIe,WAAW,eAAgB,oBAAoBC,MAAMC,QACrDV,SAASmC,SAASzB,OAClBV,SAASuB,QAAQ3B,SAASwC,aAAa,mBAAoB,oBAAqBrC,UAAWiC,YAE5FP,OAAM,KACL3B,aAAa4B,UAAU,IAAIC,MAAM,qDAUhCP,iBAAiBC,GACtBA,EAAEC,qBAGEe,aAAerC,SAASkB,UAAUoB,KAAK,QAAQC,YAC/CC,SAAWP,KAAKC,UAAUG,kBAI1BI,QAAUjD,EAAEkD,MACZ1C,SAASkB,UAAUoB,KAAK,yBACxBtC,SAASkB,UAAUoB,KAAK,WAGxBG,QAAQE,OACRF,QAAQG,QAAQC,QAKpBhD,KAAKiD,KAAK,CAAC,CACPC,WAAY,yCACZC,KAAM,cACcR,gBACNtC,WAEd,GAAG+C,MAAK,KAERjD,SAASuB,QAAQjB,SACjBN,SAASwB,OACLpB,YACAH,SAASC,OAAQE,aAEjBH,SAASC,WAEdgD,MAAK,KAEJtB,gBAAgB1B,OAAQC,OAAQkC,wBAWxChC,cAAc8C,iBAAmB,SAAUtB,KAAMC,UAAMsB,6DAAQ,KAC3DlD,OAAS2B,KACT1B,OAAS2B,KACT1B,YAAcgD,MACdxB,gBAAgBC,KAAMC,MACtB9B,SAASqD,QAUbhD,cAAciD,KAAO,SAAUC,QAASC,sBAAkBJ,6DAAQ,KAC9DrD,UAAYwD,QACZtD,SAAWuD,iBACXpD,YAAcgD,MACd7C,eAGGF"} \ No newline at end of file diff --git a/amd/build/student_search.min.js b/amd/build/student_search.min.js index 2d401351..c2b1dfed 100644 --- a/amd/build/student_search.min.js +++ b/amd/build/student_search.min.js @@ -3,7 +3,6 @@ define("local_assessfreq/student_search",["exports","jquery","core/notification" * Javascript for student search display and processing. * * @module local_assessfreq/student_search - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */var contextid;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_notification=_interopRequireDefault(_notification),_override_modal=_interopRequireDefault(_override_modal),TableHandler=_interopRequireWildcard(TableHandler),UserPreference=_interopRequireWildcard(UserPreference);var counterid,hoursAhead=4,hoursBehind=1,refreshPeriod=60;const refreshCounter=function(){let reset=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],progressElement=document.getElementById("local-assessfreq-period-progress");!0===reset&&(clearInterval(counterid),counterid=null,progressElement.setAttribute("style","width: 100%"),progressElement.setAttribute("aria-valuenow",100)),counterid||(counterid=setInterval((()=>{let progressWidthAria=progressElement.getAttribute("aria-valuenow");const progressStep=100/refreshPeriod;progressWidthAria-progressStep>0?(progressElement.setAttribute("style","width: "+(progressWidthAria-progressStep)+"%"),progressElement.setAttribute("aria-valuenow",progressWidthAria-progressStep)):(clearInterval(counterid),counterid=null,progressElement.setAttribute("style","width: 100%"),progressElement.setAttribute("aria-valuenow",100),TableHandler.getTable(0,[hoursAhead,hoursBehind],null),refreshCounter())}),1e3))},tableSearchAheadSet=event=>{if(event.preventDefault(),"a"===event.target.tagName.toLowerCase()){let hours=event.target.dataset.metric;UserPreference.setUserPreference("local_assessfreq_student_search_table_hoursahead_preference",hours).then((()=>{hoursAhead=hours,TableHandler.getTable(0,[hoursAhead,hoursBehind],null)})).fail((()=>{_notification.default.exception(new Error("Failed to update user preference: hours ahead"))}))}},tableSearchBehindSet=event=>{if(event.preventDefault(),"a"===event.target.tagName.toLowerCase()){let hours=event.target.dataset.metric;UserPreference.setUserPreference("local_assessfreq_student_search_table_hoursbehind_preference",hours).then((()=>{hoursBehind=hours,TableHandler.getTable(0,[hoursAhead,hoursBehind],null)})).fail((()=>{_notification.default.exception(new Error("Failed to update user preference: hours behind"))}))}},refreshAction=event=>{event.preventDefault();var element=event.target;null!==element.closest("button")&&"local-assessfreq-refresh-quiz-dashboard"===element.closest("button").id?(refreshCounter(!0),TableHandler.getTable(0,[hoursAhead,hoursBehind],null)):"a"===element.tagName.toLowerCase()&&(refreshPeriod=element.dataset.period,refreshCounter(!0),UserPreference.setUserPreference("local_assessfreq_quiz_refresh_preference",refreshPeriod))};_exports.init=context=>{contextid=context,TableHandler.init(0,contextid,"local-assessfreq-student-search-table","local-assessfreq-student-search","get_student_search_table","local_assessfreq_student_search_table_rows_preference","local-assessfreq-quiz-student-table-search","local_assessfreq_student_search_table","local_assessfreq_set_table_preference");let tableSearchInputElement=document.getElementById("local-assessfreq-quiz-student-table-search"),tableSearchResetElement=document.getElementById("local-assessfreq-quiz-student-table-search-reset"),tableSearchRowsElement=document.getElementById("local-assessfreq-quiz-student-table-rows"),tableSearchAheadElement=document.getElementById("local-assessfreq-quiz-student-table-hoursahead"),tableSearchBehindElement=document.getElementById("local-assessfreq-quiz-student-table-hoursbehind"),refreshElement=document.getElementById("local-assessfreq-period-container");tableSearchInputElement.addEventListener("keyup",TableHandler.tableSearch),tableSearchInputElement.addEventListener("paste",TableHandler.tableSearch),tableSearchResetElement.addEventListener("click",TableHandler.tableSearchReset),tableSearchRowsElement.addEventListener("click",TableHandler.tableSearchRowSet),tableSearchAheadElement.addEventListener("click",tableSearchAheadSet),tableSearchBehindElement.addEventListener("click",tableSearchBehindSet),refreshElement.addEventListener("click",refreshAction),_jquery.default.when(UserPreference.getUserPreference("local_assessfreq_student_search_table_hoursahead_preference").then((response=>{hoursAhead=response.preferences[0].value?response.preferences[0].value:4})).fail((()=>{_notification.default.exception(new Error("Failed to get use preference: hoursahead"))})),UserPreference.getUserPreference("local_assessfreq_student_search_table_hoursbehind_preference").then((response=>{hoursBehind=response.preferences[0].value?response.preferences[0].value:1})).fail((()=>{_notification.default.exception(new Error("Failed to get use preference: hoursahead"))}))).done((function(){TableHandler.getTable(0,[hoursAhead,hoursBehind],null),_override_modal.default.init(context,TableHandler.getTable,[hoursAhead,hoursBehind])}))}})); diff --git a/amd/build/student_search.min.js.map b/amd/build/student_search.min.js.map index 6a4a2b5b..7d134685 100644 --- a/amd/build/student_search.min.js.map +++ b/amd/build/student_search.min.js.map @@ -1 +1 @@ -{"version":3,"file":"student_search.min.js","sources":["../src/student_search.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\n/**\n * Javascript for student search display and processing.\n *\n * @module local_assessfreq/student_search\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Notification from 'core/notification';\nimport OverrideModal from 'local_assessfreq/override_modal';\nimport * as TableHandler from 'local_assessfreq/table_handler';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\n\n/**\n * Module level variables.\n */\nvar contextid;\nvar hoursAhead = 4;\nvar hoursBehind = 1;\nvar refreshPeriod = 60;\nvar counterid;\n\n/**\n * Function for refreshing the counter.\n *\n * @param {boolean} reset the current count process.\n */\nconst refreshCounter = (reset = true) => {\n let progressElement = document.getElementById('local-assessfreq-period-progress');\n\n // Reset the current count process.\n if (reset === true) {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n }\n\n // Exit early if there is already a counter running.\n if (counterid) {\n return;\n }\n\n counterid = setInterval(() => {\n let progressWidthAria = progressElement.getAttribute('aria-valuenow');\n const progressStep = 100 / refreshPeriod;\n\n if ((progressWidthAria - progressStep) > 0) {\n progressElement.setAttribute('style', 'width: ' + (progressWidthAria - progressStep) + '%');\n progressElement.setAttribute('aria-valuenow', (progressWidthAria - progressStep));\n } else {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null);\n refreshCounter();\n }\n }, (1000));\n};\n\n/**\n * Process the hours ahead event from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableSearchAheadSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let hours = event.target.dataset.metric;\n UserPreference.setUserPreference('local_assessfreq_student_search_table_hoursahead_preference', hours)\n .then(() => {\n hoursAhead = hours;\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null); // Reload the table. // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: hours ahead'));\n });\n }\n};\n\n/**\n * Process the hours behind event from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableSearchBehindSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let hours = event.target.dataset.metric;\n UserPreference.setUserPreference('local_assessfreq_student_search_table_hoursbehind_preference', hours)\n .then(() => {\n hoursBehind = hours;\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null); // Reload the table. // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: hours behind'));\n });\n }\n};\n\n/**\n * Handle processing of refresh and period button actions.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst refreshAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.closest('button') !== null && element.closest('button').id === 'local-assessfreq-refresh-quiz-dashboard') {\n refreshCounter(true);\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null);\n } else if (element.tagName.toLowerCase() === 'a') {\n refreshPeriod = element.dataset.period;\n refreshCounter(true);\n UserPreference.setUserPreference('local_assessfreq_quiz_refresh_preference', refreshPeriod);\n }\n};\n\n/**\n * Initialise method for student search.\n *\n * @param {integer} context The current context id.\n */\nexport const init = (context) => {\n contextid = context;\n TableHandler.init(\n 0,\n contextid,\n 'local-assessfreq-student-search-table',\n 'local-assessfreq-student-search',\n 'get_student_search_table',\n 'local_assessfreq_student_search_table_rows_preference',\n 'local-assessfreq-quiz-student-table-search',\n 'local_assessfreq_student_search_table',\n 'local_assessfreq_set_table_preference'\n );\n\n // Add required initial event listeners.\n let tableSearchInputElement = document.getElementById('local-assessfreq-quiz-student-table-search');\n let tableSearchResetElement = document.getElementById('local-assessfreq-quiz-student-table-search-reset');\n let tableSearchRowsElement = document.getElementById('local-assessfreq-quiz-student-table-rows');\n let tableSearchAheadElement = document.getElementById('local-assessfreq-quiz-student-table-hoursahead');\n let tableSearchBehindElement = document.getElementById('local-assessfreq-quiz-student-table-hoursbehind');\n let refreshElement = document.getElementById('local-assessfreq-period-container');\n\n tableSearchInputElement.addEventListener('keyup', TableHandler.tableSearch);\n tableSearchInputElement.addEventListener('paste', TableHandler.tableSearch);\n tableSearchResetElement.addEventListener('click', TableHandler.tableSearchReset);\n tableSearchRowsElement.addEventListener('click', TableHandler.tableSearchRowSet);\n tableSearchAheadElement.addEventListener('click', tableSearchAheadSet);\n tableSearchBehindElement.addEventListener('click', tableSearchBehindSet);\n refreshElement.addEventListener('click', refreshAction);\n\n $.when(\n UserPreference.getUserPreference('local_assessfreq_student_search_table_hoursahead_preference')\n .then((response) => {\n hoursAhead = response.preferences[0].value ? response.preferences[0].value : 4;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: hoursahead'));\n }),\n UserPreference.getUserPreference('local_assessfreq_student_search_table_hoursbehind_preference')\n .then((response) => {\n hoursBehind = response.preferences[0].value ? response.preferences[0].value : 1;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: hoursahead'));\n })\n ).done(function () {\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null);\n OverrideModal.init(context, TableHandler.getTable, [hoursAhead, hoursBehind]);\n });\n};\n"],"names":["contextid","counterid","hoursAhead","hoursBehind","refreshPeriod","refreshCounter","reset","progressElement","document","getElementById","clearInterval","setAttribute","setInterval","progressWidthAria","getAttribute","progressStep","TableHandler","getTable","tableSearchAheadSet","event","preventDefault","target","tagName","toLowerCase","hours","dataset","metric","UserPreference","setUserPreference","then","fail","exception","Error","tableSearchBehindSet","refreshAction","element","closest","id","period","context","init","tableSearchInputElement","tableSearchResetElement","tableSearchRowsElement","tableSearchAheadElement","tableSearchBehindElement","refreshElement","addEventListener","tableSearch","tableSearchReset","tableSearchRowSet","when","getUserPreference","response","preferences","value","done"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"student_search.min.js","sources":["../src/student_search.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\n/**\n * Javascript for student search display and processing.\n *\n * @module local_assessfreq/student_search\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport Notification from 'core/notification';\nimport OverrideModal from 'local_assessfreq/override_modal';\nimport * as TableHandler from 'local_assessfreq/table_handler';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\n\n/**\n * Module level variables.\n */\nvar contextid;\nvar hoursAhead = 4;\nvar hoursBehind = 1;\nvar refreshPeriod = 60;\nvar counterid;\n\n/**\n * Function for refreshing the counter.\n *\n * @param {boolean} reset the current count process.\n */\nconst refreshCounter = (reset = true) => {\n let progressElement = document.getElementById('local-assessfreq-period-progress');\n\n // Reset the current count process.\n if (reset === true) {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n }\n\n // Exit early if there is already a counter running.\n if (counterid) {\n return;\n }\n\n counterid = setInterval(() => {\n let progressWidthAria = progressElement.getAttribute('aria-valuenow');\n const progressStep = 100 / refreshPeriod;\n\n if ((progressWidthAria - progressStep) > 0) {\n progressElement.setAttribute('style', 'width: ' + (progressWidthAria - progressStep) + '%');\n progressElement.setAttribute('aria-valuenow', (progressWidthAria - progressStep));\n } else {\n clearInterval(counterid);\n counterid = null;\n progressElement.setAttribute('style', 'width: 100%');\n progressElement.setAttribute('aria-valuenow', 100);\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null);\n refreshCounter();\n }\n }, (1000));\n};\n\n/**\n * Process the hours ahead event from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableSearchAheadSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let hours = event.target.dataset.metric;\n UserPreference.setUserPreference('local_assessfreq_student_search_table_hoursahead_preference', hours)\n .then(() => {\n hoursAhead = hours;\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null); // Reload the table. // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: hours ahead'));\n });\n }\n};\n\n/**\n * Process the hours behind event from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableSearchBehindSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let hours = event.target.dataset.metric;\n UserPreference.setUserPreference('local_assessfreq_student_search_table_hoursbehind_preference', hours)\n .then(() => {\n hoursBehind = hours;\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null); // Reload the table. // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: hours behind'));\n });\n }\n};\n\n/**\n * Handle processing of refresh and period button actions.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst refreshAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.closest('button') !== null && element.closest('button').id === 'local-assessfreq-refresh-quiz-dashboard') {\n refreshCounter(true);\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null);\n } else if (element.tagName.toLowerCase() === 'a') {\n refreshPeriod = element.dataset.period;\n refreshCounter(true);\n UserPreference.setUserPreference('local_assessfreq_quiz_refresh_preference', refreshPeriod);\n }\n};\n\n/**\n * Initialise method for student search.\n *\n * @param {integer} context The current context id.\n */\nexport const init = (context) => {\n contextid = context;\n TableHandler.init(\n 0,\n contextid,\n 'local-assessfreq-student-search-table',\n 'local-assessfreq-student-search',\n 'get_student_search_table',\n 'local_assessfreq_student_search_table_rows_preference',\n 'local-assessfreq-quiz-student-table-search',\n 'local_assessfreq_student_search_table',\n 'local_assessfreq_set_table_preference'\n );\n\n // Add required initial event listeners.\n let tableSearchInputElement = document.getElementById('local-assessfreq-quiz-student-table-search');\n let tableSearchResetElement = document.getElementById('local-assessfreq-quiz-student-table-search-reset');\n let tableSearchRowsElement = document.getElementById('local-assessfreq-quiz-student-table-rows');\n let tableSearchAheadElement = document.getElementById('local-assessfreq-quiz-student-table-hoursahead');\n let tableSearchBehindElement = document.getElementById('local-assessfreq-quiz-student-table-hoursbehind');\n let refreshElement = document.getElementById('local-assessfreq-period-container');\n\n tableSearchInputElement.addEventListener('keyup', TableHandler.tableSearch);\n tableSearchInputElement.addEventListener('paste', TableHandler.tableSearch);\n tableSearchResetElement.addEventListener('click', TableHandler.tableSearchReset);\n tableSearchRowsElement.addEventListener('click', TableHandler.tableSearchRowSet);\n tableSearchAheadElement.addEventListener('click', tableSearchAheadSet);\n tableSearchBehindElement.addEventListener('click', tableSearchBehindSet);\n refreshElement.addEventListener('click', refreshAction);\n\n $.when(\n UserPreference.getUserPreference('local_assessfreq_student_search_table_hoursahead_preference')\n .then((response) => {\n hoursAhead = response.preferences[0].value ? response.preferences[0].value : 4;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: hoursahead'));\n }),\n UserPreference.getUserPreference('local_assessfreq_student_search_table_hoursbehind_preference')\n .then((response) => {\n hoursBehind = response.preferences[0].value ? response.preferences[0].value : 1;\n })\n .fail(() => {\n Notification.exception(new Error('Failed to get use preference: hoursahead'));\n })\n ).done(function () {\n TableHandler.getTable(0, [hoursAhead, hoursBehind], null);\n OverrideModal.init(context, TableHandler.getTable, [hoursAhead, hoursBehind]);\n });\n};\n"],"names":["contextid","counterid","hoursAhead","hoursBehind","refreshPeriod","refreshCounter","reset","progressElement","document","getElementById","clearInterval","setAttribute","setInterval","progressWidthAria","getAttribute","progressStep","TableHandler","getTable","tableSearchAheadSet","event","preventDefault","target","tagName","toLowerCase","hours","dataset","metric","UserPreference","setUserPreference","then","fail","exception","Error","tableSearchBehindSet","refreshAction","element","closest","id","period","context","init","tableSearchInputElement","tableSearchResetElement","tableSearchRowsElement","tableSearchAheadElement","tableSearchBehindElement","refreshElement","addEventListener","tableSearch","tableSearchReset","tableSearchRowSet","when","getUserPreference","response","preferences","value","done"],"mappings":";;;;;;;SAgCIA,yVAIAC,UAHAC,WAAa,EACbC,YAAc,EACdC,cAAgB,SAQdC,eAAiB,eAACC,iEAChBC,gBAAkBC,SAASC,eAAe,qCAGhC,IAAVH,QACAI,cAAcT,WACdA,UAAY,KACZM,gBAAgBI,aAAa,QAAS,eACtCJ,gBAAgBI,aAAa,gBAAiB,MAI9CV,YAIJA,UAAYW,aAAY,SAChBC,kBAAoBN,gBAAgBO,aAAa,uBAC/CC,aAAe,IAAMX,cAEtBS,kBAAoBE,aAAgB,GACrCR,gBAAgBI,aAAa,QAAS,WAAaE,kBAAoBE,cAAgB,KACvFR,gBAAgBI,aAAa,gBAAkBE,kBAAoBE,gBAEnEL,cAAcT,WACdA,UAAY,KACZM,gBAAgBI,aAAa,QAAS,eACtCJ,gBAAgBI,aAAa,gBAAiB,KAC9CK,aAAaC,SAAS,EAAG,CAACf,WAAYC,aAAc,MACpDE,oBAEJ,OAQFa,oBAAuBC,WACzBA,MAAMC,iBACqC,MAAvCD,MAAME,OAAOC,QAAQC,cAAuB,KACxCC,MAAQL,MAAME,OAAOI,QAAQC,OACjCC,eAAeC,kBAAkB,8DAA+DJ,OAC/FK,MAAK,KACF3B,WAAasB,MACbR,aAAaC,SAAS,EAAG,CAACf,WAAYC,aAAc,SAEvD2B,MAAK,2BACWC,UAAU,IAAIC,MAAM,uDAUvCC,qBAAwBd,WAC1BA,MAAMC,iBACqC,MAAvCD,MAAME,OAAOC,QAAQC,cAAuB,KACxCC,MAAQL,MAAME,OAAOI,QAAQC,OACjCC,eAAeC,kBAAkB,+DAAgEJ,OAChGK,MAAK,KACF1B,YAAcqB,MACdR,aAAaC,SAAS,EAAG,CAACf,WAAYC,aAAc,SAEvD2B,MAAK,2BACWC,UAAU,IAAIC,MAAM,wDAUvCE,cAAiBf,QACnBA,MAAMC,qBACFe,QAAUhB,MAAME,OAEc,OAA9Bc,QAAQC,QAAQ,WAAuD,4CAAjCD,QAAQC,QAAQ,UAAUC,IAChEhC,gBAAe,GACfW,aAAaC,SAAS,EAAG,CAACf,WAAYC,aAAc,OACX,MAAlCgC,QAAQb,QAAQC,gBACvBnB,cAAgB+B,QAAQV,QAAQa,OAChCjC,gBAAe,GACfsB,eAAeC,kBAAkB,2CAA4CxB,+BAShEmC,UACjBvC,UAAYuC,QACZvB,aAAawB,KACT,EACAxC,UACA,wCACA,kCACA,2BACA,wDACA,6CACA,wCACA,6CAIAyC,wBAA0BjC,SAASC,eAAe,8CAClDiC,wBAA0BlC,SAASC,eAAe,oDAClDkC,uBAAyBnC,SAASC,eAAe,4CACjDmC,wBAA0BpC,SAASC,eAAe,kDAClDoC,yBAA2BrC,SAASC,eAAe,mDACnDqC,eAAiBtC,SAASC,eAAe,qCAE7CgC,wBAAwBM,iBAAiB,QAAS/B,aAAagC,aAC/DP,wBAAwBM,iBAAiB,QAAS/B,aAAagC,aAC/DN,wBAAwBK,iBAAiB,QAAS/B,aAAaiC,kBAC/DN,uBAAuBI,iBAAiB,QAAS/B,aAAakC,mBAC9DN,wBAAwBG,iBAAiB,QAAS7B,qBAClD2B,yBAAyBE,iBAAiB,QAASd,sBACnDa,eAAeC,iBAAiB,QAASb,+BAEvCiB,KACExB,eAAeyB,kBAAkB,+DAChCvB,MAAMwB,WACHnD,WAAamD,SAASC,YAAY,GAAGC,MAAQF,SAASC,YAAY,GAAGC,MAAQ,KAEhFzB,MAAK,2BACWC,UAAU,IAAIC,MAAM,gDAErCL,eAAeyB,kBAAkB,gEAChCvB,MAAMwB,WACHlD,YAAckD,SAASC,YAAY,GAAGC,MAAQF,SAASC,YAAY,GAAGC,MAAQ,KAEjFzB,MAAK,2BACWC,UAAU,IAAIC,MAAM,iDAEvCwB,MAAK,WACHxC,aAAaC,SAAS,EAAG,CAACf,WAAYC,aAAc,8BACtCqC,KAAKD,QAASvB,aAAaC,SAAU,CAACf,WAAYC"} \ No newline at end of file diff --git a/amd/build/summary_participants.min.js b/amd/build/summary_participants.min.js index ddb38848..e03b1e59 100644 --- a/amd/build/summary_participants.min.js +++ b/amd/build/summary_participants.min.js @@ -1,7 +1,6 @@ /** * Javascript for summary participants graph. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/build/summary_participants.min.js.map b/amd/build/summary_participants.min.js.map index 2cc47b52..1897539d 100644 --- a/amd/build/summary_participants.min.js.map +++ b/amd/build/summary_participants.min.js.map @@ -1 +1 @@ -{"version":3,"file":"summary_participants.min.js","sources":["../src/summary_participants.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\n/**\n * Javascript for summary participants graph.\n *\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['core/fragment', 'core/templates', 'core/str', 'core/notification'],\n function (Fragment, Templates, Str, Notification) {\n\n /**\n * Module level variables.\n */\n var Summary = {};\n\n Summary.chart = function (assessids, contextid) {\n assessids.forEach((assessid) => {\n let chartElement = document.getElementById(assessid + '-summary-graph');\n let params = {'data': JSON.stringify({'quiz' : assessid, 'call': 'participant_summary'})};\n\n Fragment.loadFragment('local_assessfreq', 'get_quiz_chart', contextid, params)\n .done((response) => {\n let resObj = JSON.parse(response);\n if (resObj.hasdata == true) {\n let legend = {position: 'left'};\n let context = {\n 'withtable' : false,\n 'chartdata' : JSON.stringify(resObj.chart),\n 'aspect' : false,\n 'legend' : JSON.stringify(legend)\n };\n Templates.render('local_assessfreq/chart', context).done((html, js) => {\n // Load card body.\n Templates.replaceNodeContents(chartElement, html, js);\n }).fail(() => {\n Notification.exception(new Error('Failed to load chart template.'));\n return;\n });\n return;\n } else {\n Str.get_string('nodata', 'local_assessfreq').then((str) => {\n const noDatastr = document.createElement('h3');\n noDatastr.innerHTML = str;\n chartElement.innerHTML = noDatastr.outerHTML;\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: nodata'));\n });\n }\n }).fail(() => {\n Notification.exception(new Error('Failed to load card.'));\n return;\n });\n });\n };\n\n return Summary;\n }\n);\n"],"names":["define","Fragment","Templates","Str","Notification","Summary","assessids","contextid","forEach","assessid","chartElement","document","getElementById","params","JSON","stringify","loadFragment","done","response","resObj","parse","hasdata","get_string","then","str","noDatastr","createElement","innerHTML","outerHTML","catch","exception","Error","legend","position","context","chart","render","html","js","replaceNodeContents","fail"],"mappings":";;;;;;;AAuBAA,+CACI,CAAC,gBAAiB,iBAAkB,WAAY,sBAChD,SAAUC,SAAUC,UAAWC,IAAKC,kBAK5BC,QAAU,CAEdA,MAAgB,SAAUC,UAAWC,WACjCD,UAAUE,SAASC,eACXC,aAAeC,SAASC,eAAeH,SAAW,kBAClDI,OAAS,MAASC,KAAKC,UAAU,MAAUN,cAAkB,yBAEjER,SAASe,aAAa,mBAAoB,iBAAkBT,UAAWM,QACtEI,MAAMC,eACCC,OAASL,KAAKM,MAAMF,aACF,GAAlBC,OAAOE,QAiBPlB,IAAImB,WAAW,SAAU,oBAAoBC,MAAMC,YACzCC,UAAYd,SAASe,cAAc,MACzCD,UAAUE,UAAYH,IACtBd,aAAaiB,UAAYF,UAAUG,aAEpCC,OAAM,KACLzB,aAAa0B,UAAU,IAAIC,MAAM,8CAtBjCC,OAAS,CAACC,SAAU,QACpBC,QAAU,YACI,YACApB,KAAKC,UAAUI,OAAOgB,eACzB,SACArB,KAAKC,UAAUiB,SAE9B9B,UAAUkC,OAAO,yBAA0BF,SAASjB,MAAK,CAACoB,KAAMC,MAE5DpC,UAAUqC,oBAAoB7B,aAAc2B,KAAMC,OACnDE,MAAK,KACJpC,aAAa0B,UAAU,IAAIC,MAAM,0CAc1CS,MAAK,KACJpC,aAAa0B,UAAU,IAAIC,MAAM,wCAMtC1B"} \ No newline at end of file +{"version":3,"file":"summary_participants.min.js","sources":["../src/summary_participants.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\n/**\n * Javascript for summary participants graph.\n *\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['core/fragment', 'core/templates', 'core/str', 'core/notification'],\n function (Fragment, Templates, Str, Notification) {\n\n /**\n * Module level variables.\n */\n var Summary = {};\n\n Summary.chart = function (assessids, contextid) {\n assessids.forEach((assessid) => {\n let chartElement = document.getElementById(assessid + '-summary-graph');\n let params = {'data': JSON.stringify({'quiz' : assessid, 'call': 'participant_summary'})};\n\n Fragment.loadFragment('local_assessfreq', 'get_quiz_chart', contextid, params)\n .done((response) => {\n let resObj = JSON.parse(response);\n if (resObj.hasdata == true) {\n let legend = {position: 'left'};\n let context = {\n 'withtable' : false,\n 'chartdata' : JSON.stringify(resObj.chart),\n 'aspect' : false,\n 'legend' : JSON.stringify(legend)\n };\n Templates.render('local_assessfreq/chart', context).done((html, js) => {\n // Load card body.\n Templates.replaceNodeContents(chartElement, html, js);\n }).fail(() => {\n Notification.exception(new Error('Failed to load chart template.'));\n return;\n });\n return;\n } else {\n Str.get_string('nodata', 'local_assessfreq').then((str) => {\n const noDatastr = document.createElement('h3');\n noDatastr.innerHTML = str;\n chartElement.innerHTML = noDatastr.outerHTML;\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: nodata'));\n });\n }\n }).fail(() => {\n Notification.exception(new Error('Failed to load card.'));\n return;\n });\n });\n };\n\n return Summary;\n }\n);\n"],"names":["define","Fragment","Templates","Str","Notification","Summary","assessids","contextid","forEach","assessid","chartElement","document","getElementById","params","JSON","stringify","loadFragment","done","response","resObj","parse","hasdata","get_string","then","str","noDatastr","createElement","innerHTML","outerHTML","catch","exception","Error","legend","position","context","chart","render","html","js","replaceNodeContents","fail"],"mappings":";;;;;;AAsBAA,+CACI,CAAC,gBAAiB,iBAAkB,WAAY,sBAChD,SAAUC,SAAUC,UAAWC,IAAKC,kBAK5BC,QAAU,CAEdA,MAAgB,SAAUC,UAAWC,WACjCD,UAAUE,SAASC,eACXC,aAAeC,SAASC,eAAeH,SAAW,kBAClDI,OAAS,MAASC,KAAKC,UAAU,MAAUN,cAAkB,yBAEjER,SAASe,aAAa,mBAAoB,iBAAkBT,UAAWM,QACtEI,MAAMC,eACCC,OAASL,KAAKM,MAAMF,aACF,GAAlBC,OAAOE,QAiBPlB,IAAImB,WAAW,SAAU,oBAAoBC,MAAMC,YACzCC,UAAYd,SAASe,cAAc,MACzCD,UAAUE,UAAYH,IACtBd,aAAaiB,UAAYF,UAAUG,aAEpCC,OAAM,KACLzB,aAAa0B,UAAU,IAAIC,MAAM,8CAtBjCC,OAAS,CAACC,SAAU,QACpBC,QAAU,YACI,YACApB,KAAKC,UAAUI,OAAOgB,eACzB,SACArB,KAAKC,UAAUiB,SAE9B9B,UAAUkC,OAAO,yBAA0BF,SAASjB,MAAK,CAACoB,KAAMC,MAE5DpC,UAAUqC,oBAAoB7B,aAAc2B,KAAMC,OACnDE,MAAK,KACJpC,aAAa0B,UAAU,IAAIC,MAAM,0CAc1CS,MAAK,KACJpC,aAAa0B,UAAU,IAAIC,MAAM,wCAMtC1B"} \ No newline at end of file diff --git a/amd/build/table_handler.min.js b/amd/build/table_handler.min.js index 6e42ce2d..6b506324 100644 --- a/amd/build/table_handler.min.js +++ b/amd/build/table_handler.min.js @@ -3,7 +3,6 @@ define("local_assessfreq/table_handler",["exports","core/ajax","core/fragment"," * Table handler JS module. * * @module local_assessfreq/table_handler - * @package local_assessfreq * @copyright 2020 Guillermo Gomez * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */let cardElement,contextId,elementId,fragmentValue,hoursFilter;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.tableSortButtonAction=_exports.tableSearchRowSet=_exports.tableSearchReset=_exports.tableSearch=_exports.init=_exports.getTable=void 0,_ajax=_interopRequireDefault(_ajax),_fragment=_interopRequireDefault(_fragment),_notification=_interopRequireDefault(_notification),_templates=_interopRequireDefault(_templates),Debouncer=_interopRequireWildcard(Debouncer),_override_modal=_interopRequireDefault(_override_modal),UserPreference=_interopRequireWildcard(UserPreference);let rowPreference,sortValue,searchElement,id,methodName,quizId=0,overridden=!1;const getTable=function(quiz){let hours=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,sortValueTable=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,page=arguments.length>3?arguments[3]:void 0;void 0!==page&&!0!==overridden||(page=0),overridden=!1;let search=document.getElementById(searchElement).value.trim(),tableElement=document.getElementById(elementId),spinner=tableElement.getElementsByClassName("overlay-icon-container")[0],tableBody=tableElement.getElementsByClassName("table-body")[0],values={search:search,page:page};if(quiz>0&&(quizId=quiz,values.quiz=quizId),hours&&(hoursFilter=hours,values.hoursahead=hoursFilter[0],values.hoursbehind=hoursFilter[1]),sortValueTable){sortValue=sortValueTable;let sortArray=sortValue.split("_"),sortOn=sortArray[0],direction=sortArray[1];values.sorton=sortOn,values.direction=direction}let params={data:JSON.stringify(values)};spinner.classList.remove("hide"),_fragment.default.loadFragment("local_assessfreq",fragmentValue,contextId,params).done(((response,js)=>{tableBody.innerHTML=response,js&&_templates.default.runTemplateJS(js),spinner.classList.add("hide"),tableEventListeners()})).fail((()=>{_notification.default.exception(new Error("Failed to update table."))}))};_exports.getTable=getTable;const debounceTable=Debouncer.debouncer((()=>{getTable(quizId,hoursFilter,sortValue)}),750),tableSort=event=>{event.preventDefault();let sortArray={};const linkUrl=new URL(event.target.closest("a").href),targetSortBy=linkUrl.searchParams.get("tsort");let targetSortOrder=linkUrl.searchParams.get("tdir");""===targetSortOrder&&(targetSortOrder="4"),sortArray[targetSortBy]=targetSortOrder,_ajax.default.call([{methodname:methodName,args:{tableid:id,preference:"sortby",values:JSON.stringify(sortArray)}}])[0].then((()=>{getTable(quizId,hoursFilter,sortValue)}))},tableHide=event=>{event.preventDefault();let hideArray={};const linkUrl=new URL(event.target.closest("a").href),links=document.getElementById(elementId).querySelectorAll("a");let targetAction,targetColumn,action,column;-1!==linkUrl.search.indexOf("thide")?(targetAction="hide",targetColumn=linkUrl.searchParams.get("thide")):(targetAction="show",targetColumn=linkUrl.searchParams.get("tshow"));for(let i=0;i{getTable(quizId,hoursFilter,sortValue)}))},tableReset=event=>{event.preventDefault(),_ajax.default.call([{methodname:methodName,args:{tableid:id,preference:"reset",values:JSON.stringify({})}}])[0].then((()=>{getTable(quizId,hoursFilter,sortValue)}))};_exports.tableSearch=event=>{if("Meta"===event.key||event.ctrlKey)return!1;(0===event.target.value.length||event.target.value.length>2)&&debounceTable()};_exports.tableSearchReset=()=>{let tableSearchInputElement=document.getElementById(searchElement);tableSearchInputElement.value="",tableSearchInputElement.focus(),getTable(quizId,hoursFilter,sortValue)};_exports.tableSearchRowSet=event=>{if(event.preventDefault(),"a"===event.target.tagName.toLowerCase()){let rows=event.target.dataset.metric;UserPreference.setUserPreference(rowPreference,rows).then((()=>{getTable(quizId,hoursFilter,sortValue)})).fail((()=>{_notification.default.exception(new Error("Failed to update user preference: rows"))}))}};const tableNav=event=>{event.preventDefault();const page=new URL(event.target.closest("a").href).searchParams.get("page");page&&getTable(quizId,hoursFilter,sortValue,page)};_exports.tableSortButtonAction=event=>{event.preventDefault();var element=event.target;if("a"===element.tagName.toLowerCase()&&element.dataset.sort!==sortValue){sortValue=element.dataset.sort;let links=element.parentNode.getElementsByTagName("a");for(let i=0;i{const tableElement=document.getElementById(elementId);let tableNavElement;if(cardElement){const tableCardElement=document.getElementById(cardElement),links=tableElement.querySelectorAll("a"),resetLink=tableElement.getElementsByClassName("resettable"),overrideLinks=tableElement.getElementsByClassName("action-icon override"),disabledLinks=tableElement.getElementsByClassName("action-icon disabled");tableNavElement=tableCardElement.querySelectorAll("nav");for(let i=0;i0&&resetLink[0].addEventListener("click",tableReset);for(let i=0;i{event.preventDefault()}))}else tableNavElement=tableElement.querySelectorAll("nav");tableNavElement.forEach((navElement=>{navElement.addEventListener("click",tableNav)}))},triggerOverrideModal=event=>{event.preventDefault();let userid=event.target.closest("a").id.substring(25);if(userid.includes("-")){let elements=userid.split("-");quizId=elements.pop(),userid=elements.pop()}_override_modal.default.displayModalForm(quizId,userid,hoursFilter)};_exports.init=function(quiz,context,tableCardElement,tableElementId,tableFragmentValue,tableRowPreference,tableSearchElement){let tableId=arguments.length>7&&void 0!==arguments[7]?arguments[7]:null,tableMethodName=arguments.length>8&&void 0!==arguments[8]?arguments[8]:null;quizId=quiz,contextId=context,cardElement=tableCardElement,elementId=tableElementId,fragmentValue=tableFragmentValue,rowPreference=tableRowPreference,searchElement=tableSearchElement,id=tableId,methodName=tableMethodName}})); diff --git a/amd/build/table_handler.min.js.map b/amd/build/table_handler.min.js.map index 79e834c8..8fb95138 100644 --- a/amd/build/table_handler.min.js.map +++ b/amd/build/table_handler.min.js.map @@ -1 +1 @@ -{"version":3,"file":"table_handler.min.js","sources":["../src/table_handler.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\n/**\n * Table handler JS module.\n *\n * @module local_assessfreq/table_handler\n * @package local_assessfreq\n * @copyright 2020 Guillermo Gomez \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Fragment from 'core/fragment';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport * as Debouncer from 'local_assessfreq/debouncer';\nimport OverrideModal from 'local_assessfreq/override_modal';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\n\n/**\n * Module level variables.\n */\nlet cardElement;\nlet contextId;\nlet elementId;\nlet fragmentValue;\nlet hoursFilter;\nlet quizId = 0;\nlet overridden = false;\nlet rowPreference;\nlet sortValue;\nlet searchElement;\n\n/**\n * Table id variable.\n *\n * @type {string}\n */\nlet id;\n\n/**\n * Table method name variable.\n *\n * @type {string}\n */\nlet methodName;\n\n/**\n * Display the table that contains all the students in the exam as well as their attempts.\n *\n * @param {int} quiz The Quiz Id.\n * @param {array|null} hours Array with hour ahead or behind preference.\n * @param {string|null} sortValueTable Sort preference.\n * @param {int|string|null} page Page number.\n */\nexport const getTable = (quiz, hours = null, sortValueTable = null, page) => {\n if (typeof page === \"undefined\" || overridden === true) {\n page = 0;\n }\n\n overridden = false;\n\n let search = document.getElementById(searchElement).value.trim();\n let tableElement = document.getElementById(elementId);\n let spinner = tableElement.getElementsByClassName('overlay-icon-container')[0];\n let tableBody = tableElement.getElementsByClassName('table-body')[0];\n let values = {'search': search, 'page': page};\n\n // Add values to Object depending on dashboard type.\n if (quiz > 0) {\n quizId = quiz;\n values.quiz = quizId;\n }\n if (hours) {\n hoursFilter = hours;\n values.hoursahead = hoursFilter[0];\n values.hoursbehind = hoursFilter[1];\n }\n if (sortValueTable) {\n sortValue = sortValueTable;\n let sortArray = sortValue.split('_');\n let sortOn = sortArray[0];\n let direction = sortArray[1];\n values.sorton = sortOn;\n values.direction = direction;\n }\n\n let params = {'data': JSON.stringify(values)};\n\n spinner.classList.remove('hide'); // Show spinner if not already shown.\n Fragment.loadFragment('local_assessfreq', fragmentValue, contextId, params)\n .done((response, js) => {\n tableBody.innerHTML = response;\n if (js) {\n Templates.runTemplateJS(js); // Magic call the initialises JS from template included in response template HTML.\n }\n spinner.classList.add('hide');\n tableEventListeners(); // Re-add table event listeners.\n\n }).fail(() => {\n Notification.exception(new Error('Failed to update table.'));\n });\n};\n\n/**\n * This stops the ajax method that updates the table from being updated\n * while the user is still checking options.\n *\n */\nconst debounceTable = Debouncer.debouncer(() => {\n getTable(quizId, hoursFilter, sortValue);\n}, 750);\n\n/**\n * Process the sort click events from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableSort = (event) => {\n event.preventDefault();\n\n let sortArray = {};\n const linkUrl = new URL(event.target.closest('a').href);\n const targetSortBy = linkUrl.searchParams.get('tsort');\n let targetSortOrder = linkUrl.searchParams.get('tdir');\n\n // We want to flip the clicked column.\n if (targetSortOrder === '') {\n targetSortOrder = \"4\";\n }\n\n sortArray[targetSortBy] = targetSortOrder;\n\n // Set option via ajax.\n Ajax.call([{\n methodname: methodName,\n args: {\n tableid: id,\n preference: 'sortby',\n values: JSON.stringify(sortArray)\n },\n }])[0].then(() => {\n getTable(quizId, hoursFilter, sortValue); // Reload the table.\n });\n\n};\n\n/**\n * Process the sort click events from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableHide = (event) => {\n event.preventDefault();\n\n let hideArray = {};\n const linkUrl = new URL(event.target.closest('a').href);\n const tableElement = document.getElementById(elementId);\n const links = tableElement.querySelectorAll('a');\n let targetAction;\n let targetColumn;\n let action;\n let column;\n\n if (linkUrl.search.indexOf('thide') !== -1) {\n targetAction = 'hide';\n targetColumn = linkUrl.searchParams.get('thide');\n } else {\n targetAction = 'show';\n targetColumn = linkUrl.searchParams.get('tshow');\n }\n\n for (let i = 0; i < links.length; i++) {\n let hideLinkUrl = new URL(links[i].href);\n if (hideLinkUrl.search.indexOf('thide') !== -1) {\n action = 'hide';\n column = hideLinkUrl.searchParams.get('thide');\n } else {\n action = 'show';\n column = hideLinkUrl.searchParams.get('tshow');\n }\n\n if (action === 'show') {\n hideArray[column] = 1;\n }\n }\n\n hideArray[targetColumn] = (targetAction === 'hide') ? 1 : 0; // We want to flip the clicked column.\n\n // Set option via ajax.\n Ajax.call([{\n methodname: methodName,\n args: {\n tableid: id,\n preference: 'collapse',\n values: JSON.stringify(hideArray)\n },\n }])[0].then(() => {\n getTable(quizId, hoursFilter, sortValue); // Reload the table.\n });\n\n};\n\n/**\n * Process the reset click event from the table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableReset = (event) => {\n event.preventDefault();\n\n // Set option via ajax.\n Ajax.call([{\n methodname: methodName,\n args: {\n tableid: id,\n preference: 'reset',\n values: JSON.stringify({})\n },\n }])[0].then(() => {\n getTable(quizId, hoursFilter, sortValue); // Reload the table.\n });\n\n};\n\n/**\n * Process the search events from the student table.\n *\n */\nexport const tableSearch = (event) => {\n if (event.key === 'Meta' || event.ctrlKey) {\n return false;\n }\n\n if (event.target.value.length === 0 || event.target.value.length > 2) {\n debounceTable();\n }\n};\n\n/**\n * Process the search reset click event from the student table.\n *\n */\nexport const tableSearchReset = () => {\n let tableSearchInputElement = document.getElementById(searchElement);\n tableSearchInputElement.value = '';\n tableSearchInputElement.focus();\n getTable(quizId, hoursFilter, sortValue);\n};\n\n/**\n * Process the row set event from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nexport const tableSearchRowSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let rows = event.target.dataset.metric;\n UserPreference.setUserPreference(rowPreference, rows)\n .then(() => {\n getTable(quizId, hoursFilter, sortValue); // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: rows'));\n });\n }\n};\n\n/**\n * Process the nav event from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableNav = (event) => {\n event.preventDefault();\n\n const linkUrl = new URL(event.target.closest('a').href);\n const page = linkUrl.searchParams.get('page');\n\n if (page) {\n getTable(quizId, hoursFilter, sortValue, page);\n }\n};\n\n/**\n * Get and process the selected assessment metric from the dropdown for the heatmap display,\n * and update the corresponding user preference.\n *\n * @param {Event} event The triggered event for the element.\n */\nexport const tableSortButtonAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.tagName.toLowerCase() === 'a' && element.dataset.sort !== sortValue) {\n sortValue = element.dataset.sort;\n\n let links = element.parentNode.getElementsByTagName('a');\n for (let i = 0; i < links.length; i++) {\n links[i].classList.remove('active');\n }\n\n element.classList.add('active');\n\n // Save selection as a user preference.\n UserPreference.setUserPreference('local_assessfreq_quiz_table_inprogress_sort_preference', sortValue);\n\n debounceTable(); // Call function to update table.\n }\n};\n\n/**\n * Re-add event listeners when the student table is updated.\n */\nconst tableEventListeners = () => {\n const tableElement = document.getElementById(elementId);\n let tableNavElement;\n if (cardElement) {\n const tableCardElement = document.getElementById(cardElement);\n const links = tableElement.querySelectorAll('a');\n const resetLink = tableElement.getElementsByClassName('resettable');\n const overrideLinks = tableElement.getElementsByClassName('action-icon override');\n const disabledLinks = tableElement.getElementsByClassName('action-icon disabled');\n tableNavElement = tableCardElement.querySelectorAll('nav'); // There are two nav paging elements per table.\n\n for (let i = 0; i < links.length; i++) {\n let linkUrl = new URL(links[i].href);\n if (linkUrl.search.indexOf('thide') !== -1 || linkUrl.search.indexOf('tshow') !== -1) {\n links[i].addEventListener('click', tableHide);\n } else if (linkUrl.search.indexOf('tsort') !== -1) {\n links[i].addEventListener('click', tableSort);\n }\n }\n\n if (resetLink.length > 0) {\n resetLink[0].addEventListener('click', tableReset);\n }\n\n for (let i = 0; i < overrideLinks.length; i++) {\n overrideLinks[i].addEventListener('click', triggerOverrideModal);\n }\n\n for (let i = 0; i < disabledLinks.length; i++) {\n disabledLinks[i].addEventListener('click', (event) => {\n event.preventDefault();\n });\n }\n } else {\n tableNavElement = tableElement.querySelectorAll('nav');\n }\n\n tableNavElement.forEach((navElement) => {\n navElement.addEventListener('click', tableNav);\n });\n};\n\n/**\n * Trigger the override modal form. Thin wrapper to add extra data to click event.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst triggerOverrideModal = (event) => {\n event.preventDefault();\n let userid = event.target.closest('a').id.substring(25);\n if (userid.includes('-')) {\n let elements = userid.split('-');\n quizId = elements.pop();\n userid = elements.pop();\n }\n\n OverrideModal.displayModalForm(quizId, userid, hoursFilter);\n};\n\n/**\n * Initialise method for table handler.\n *\n * @param {int} quiz The quiz id.\n * @param {int} context The context id.\n * @param {string} tableCardElement The table card element.\n * @param {string} tableElementId The table element id.\n * @param {string} tableFragmentValue The table fragment value.\n * @param {string} tableRowPreference The table row preference.\n * @param {string} tableSearchElement The table search element.\n * @param {string|null} tableId The table id.\n * @param {string|null} tableMethodName The table method name.\n */\nexport const init = (quiz,\n context,\n tableCardElement,\n tableElementId,\n tableFragmentValue,\n tableRowPreference,\n tableSearchElement,\n tableId = null,\n tableMethodName = null) => {\n quizId = quiz;\n contextId = context;\n cardElement = tableCardElement;\n elementId = tableElementId;\n fragmentValue = tableFragmentValue;\n rowPreference = tableRowPreference;\n searchElement = tableSearchElement;\n id = tableId;\n methodName = tableMethodName;\n };\n"],"names":["cardElement","contextId","elementId","fragmentValue","hoursFilter","rowPreference","sortValue","searchElement","id","methodName","quizId","overridden","getTable","quiz","hours","sortValueTable","page","search","document","getElementById","value","trim","tableElement","spinner","getElementsByClassName","tableBody","values","hoursahead","hoursbehind","sortArray","split","sortOn","direction","sorton","params","JSON","stringify","classList","remove","loadFragment","done","response","js","innerHTML","runTemplateJS","add","tableEventListeners","fail","exception","Error","debounceTable","Debouncer","debouncer","tableSort","event","preventDefault","linkUrl","URL","target","closest","href","targetSortBy","searchParams","get","targetSortOrder","call","methodname","args","tableid","preference","then","tableHide","hideArray","links","querySelectorAll","targetAction","targetColumn","action","column","indexOf","i","length","hideLinkUrl","tableReset","key","ctrlKey","tableSearchInputElement","focus","tagName","toLowerCase","rows","dataset","metric","UserPreference","setUserPreference","tableNav","element","sort","parentNode","getElementsByTagName","tableNavElement","tableCardElement","resetLink","overrideLinks","disabledLinks","addEventListener","triggerOverrideModal","forEach","navElement","userid","substring","includes","elements","pop","displayModalForm","context","tableElementId","tableFragmentValue","tableRowPreference","tableSearchElement","tableId","tableMethodName"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"table_handler.min.js","sources":["../src/table_handler.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\n/**\n * Table handler JS module.\n *\n * @module local_assessfreq/table_handler\n * @copyright 2020 Guillermo Gomez \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Fragment from 'core/fragment';\nimport Notification from 'core/notification';\nimport Templates from 'core/templates';\nimport * as Debouncer from 'local_assessfreq/debouncer';\nimport OverrideModal from 'local_assessfreq/override_modal';\nimport * as UserPreference from 'local_assessfreq/user_preferences';\n\n/**\n * Module level variables.\n */\nlet cardElement;\nlet contextId;\nlet elementId;\nlet fragmentValue;\nlet hoursFilter;\nlet quizId = 0;\nlet overridden = false;\nlet rowPreference;\nlet sortValue;\nlet searchElement;\n\n/**\n * Table id variable.\n *\n * @type {string}\n */\nlet id;\n\n/**\n * Table method name variable.\n *\n * @type {string}\n */\nlet methodName;\n\n/**\n * Display the table that contains all the students in the exam as well as their attempts.\n *\n * @param {int} quiz The Quiz Id.\n * @param {array|null} hours Array with hour ahead or behind preference.\n * @param {string|null} sortValueTable Sort preference.\n * @param {int|string|null} page Page number.\n */\nexport const getTable = (quiz, hours = null, sortValueTable = null, page) => {\n if (typeof page === \"undefined\" || overridden === true) {\n page = 0;\n }\n\n overridden = false;\n\n let search = document.getElementById(searchElement).value.trim();\n let tableElement = document.getElementById(elementId);\n let spinner = tableElement.getElementsByClassName('overlay-icon-container')[0];\n let tableBody = tableElement.getElementsByClassName('table-body')[0];\n let values = {'search': search, 'page': page};\n\n // Add values to Object depending on dashboard type.\n if (quiz > 0) {\n quizId = quiz;\n values.quiz = quizId;\n }\n if (hours) {\n hoursFilter = hours;\n values.hoursahead = hoursFilter[0];\n values.hoursbehind = hoursFilter[1];\n }\n if (sortValueTable) {\n sortValue = sortValueTable;\n let sortArray = sortValue.split('_');\n let sortOn = sortArray[0];\n let direction = sortArray[1];\n values.sorton = sortOn;\n values.direction = direction;\n }\n\n let params = {'data': JSON.stringify(values)};\n\n spinner.classList.remove('hide'); // Show spinner if not already shown.\n Fragment.loadFragment('local_assessfreq', fragmentValue, contextId, params)\n .done((response, js) => {\n tableBody.innerHTML = response;\n if (js) {\n Templates.runTemplateJS(js); // Magic call the initialises JS from template included in response template HTML.\n }\n spinner.classList.add('hide');\n tableEventListeners(); // Re-add table event listeners.\n\n }).fail(() => {\n Notification.exception(new Error('Failed to update table.'));\n });\n};\n\n/**\n * This stops the ajax method that updates the table from being updated\n * while the user is still checking options.\n *\n */\nconst debounceTable = Debouncer.debouncer(() => {\n getTable(quizId, hoursFilter, sortValue);\n}, 750);\n\n/**\n * Process the sort click events from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableSort = (event) => {\n event.preventDefault();\n\n let sortArray = {};\n const linkUrl = new URL(event.target.closest('a').href);\n const targetSortBy = linkUrl.searchParams.get('tsort');\n let targetSortOrder = linkUrl.searchParams.get('tdir');\n\n // We want to flip the clicked column.\n if (targetSortOrder === '') {\n targetSortOrder = \"4\";\n }\n\n sortArray[targetSortBy] = targetSortOrder;\n\n // Set option via ajax.\n Ajax.call([{\n methodname: methodName,\n args: {\n tableid: id,\n preference: 'sortby',\n values: JSON.stringify(sortArray)\n },\n }])[0].then(() => {\n getTable(quizId, hoursFilter, sortValue); // Reload the table.\n });\n\n};\n\n/**\n * Process the sort click events from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableHide = (event) => {\n event.preventDefault();\n\n let hideArray = {};\n const linkUrl = new URL(event.target.closest('a').href);\n const tableElement = document.getElementById(elementId);\n const links = tableElement.querySelectorAll('a');\n let targetAction;\n let targetColumn;\n let action;\n let column;\n\n if (linkUrl.search.indexOf('thide') !== -1) {\n targetAction = 'hide';\n targetColumn = linkUrl.searchParams.get('thide');\n } else {\n targetAction = 'show';\n targetColumn = linkUrl.searchParams.get('tshow');\n }\n\n for (let i = 0; i < links.length; i++) {\n let hideLinkUrl = new URL(links[i].href);\n if (hideLinkUrl.search.indexOf('thide') !== -1) {\n action = 'hide';\n column = hideLinkUrl.searchParams.get('thide');\n } else {\n action = 'show';\n column = hideLinkUrl.searchParams.get('tshow');\n }\n\n if (action === 'show') {\n hideArray[column] = 1;\n }\n }\n\n hideArray[targetColumn] = (targetAction === 'hide') ? 1 : 0; // We want to flip the clicked column.\n\n // Set option via ajax.\n Ajax.call([{\n methodname: methodName,\n args: {\n tableid: id,\n preference: 'collapse',\n values: JSON.stringify(hideArray)\n },\n }])[0].then(() => {\n getTable(quizId, hoursFilter, sortValue); // Reload the table.\n });\n\n};\n\n/**\n * Process the reset click event from the table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableReset = (event) => {\n event.preventDefault();\n\n // Set option via ajax.\n Ajax.call([{\n methodname: methodName,\n args: {\n tableid: id,\n preference: 'reset',\n values: JSON.stringify({})\n },\n }])[0].then(() => {\n getTable(quizId, hoursFilter, sortValue); // Reload the table.\n });\n\n};\n\n/**\n * Process the search events from the student table.\n *\n * @param {Event} event The triggered event for the element.\n *\n */\nexport const tableSearch = (event) => {\n if (event.key === 'Meta' || event.ctrlKey) {\n return false;\n }\n\n if (event.target.value.length === 0 || event.target.value.length > 2) {\n debounceTable();\n }\n};\n\n/**\n * Process the search reset click event from the student table.\n *\n */\nexport const tableSearchReset = () => {\n let tableSearchInputElement = document.getElementById(searchElement);\n tableSearchInputElement.value = '';\n tableSearchInputElement.focus();\n getTable(quizId, hoursFilter, sortValue);\n};\n\n/**\n * Process the row set event from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nexport const tableSearchRowSet = (event) => {\n event.preventDefault();\n if (event.target.tagName.toLowerCase() === 'a') {\n let rows = event.target.dataset.metric;\n UserPreference.setUserPreference(rowPreference, rows)\n .then(() => {\n getTable(quizId, hoursFilter, sortValue); // Reload the table.\n })\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference: rows'));\n });\n }\n};\n\n/**\n * Process the nav event from the student table.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst tableNav = (event) => {\n event.preventDefault();\n\n const linkUrl = new URL(event.target.closest('a').href);\n const page = linkUrl.searchParams.get('page');\n\n if (page) {\n getTable(quizId, hoursFilter, sortValue, page);\n }\n};\n\n/**\n * Get and process the selected assessment metric from the dropdown for the heatmap display,\n * and update the corresponding user preference.\n *\n * @param {Event} event The triggered event for the element.\n */\nexport const tableSortButtonAction = (event) => {\n event.preventDefault();\n var element = event.target;\n\n if (element.tagName.toLowerCase() === 'a' && element.dataset.sort !== sortValue) {\n sortValue = element.dataset.sort;\n\n let links = element.parentNode.getElementsByTagName('a');\n for (let i = 0; i < links.length; i++) {\n links[i].classList.remove('active');\n }\n\n element.classList.add('active');\n\n // Save selection as a user preference.\n UserPreference.setUserPreference('local_assessfreq_quiz_table_inprogress_sort_preference', sortValue);\n\n debounceTable(); // Call function to update table.\n }\n};\n\n/**\n * Re-add event listeners when the student table is updated.\n */\nconst tableEventListeners = () => {\n const tableElement = document.getElementById(elementId);\n let tableNavElement;\n if (cardElement) {\n const tableCardElement = document.getElementById(cardElement);\n const links = tableElement.querySelectorAll('a');\n const resetLink = tableElement.getElementsByClassName('resettable');\n const overrideLinks = tableElement.getElementsByClassName('action-icon override');\n const disabledLinks = tableElement.getElementsByClassName('action-icon disabled');\n tableNavElement = tableCardElement.querySelectorAll('nav'); // There are two nav paging elements per table.\n\n for (let i = 0; i < links.length; i++) {\n let linkUrl = new URL(links[i].href);\n if (linkUrl.search.indexOf('thide') !== -1 || linkUrl.search.indexOf('tshow') !== -1) {\n links[i].addEventListener('click', tableHide);\n } else if (linkUrl.search.indexOf('tsort') !== -1) {\n links[i].addEventListener('click', tableSort);\n }\n }\n\n if (resetLink.length > 0) {\n resetLink[0].addEventListener('click', tableReset);\n }\n\n for (let i = 0; i < overrideLinks.length; i++) {\n overrideLinks[i].addEventListener('click', triggerOverrideModal);\n }\n\n for (let i = 0; i < disabledLinks.length; i++) {\n disabledLinks[i].addEventListener('click', (event) => {\n event.preventDefault();\n });\n }\n } else {\n tableNavElement = tableElement.querySelectorAll('nav');\n }\n\n tableNavElement.forEach((navElement) => {\n navElement.addEventListener('click', tableNav);\n });\n};\n\n/**\n * Trigger the override modal form. Thin wrapper to add extra data to click event.\n *\n * @param {Event} event The triggered event for the element.\n */\nconst triggerOverrideModal = (event) => {\n event.preventDefault();\n let userid = event.target.closest('a').id.substring(25);\n if (userid.includes('-')) {\n let elements = userid.split('-');\n quizId = elements.pop();\n userid = elements.pop();\n }\n\n OverrideModal.displayModalForm(quizId, userid, hoursFilter);\n};\n\n/**\n * Initialise method for table handler.\n *\n * @param {int} quiz The quiz id.\n * @param {int} context The context id.\n * @param {string} tableCardElement The table card element.\n * @param {string} tableElementId The table element id.\n * @param {string} tableFragmentValue The table fragment value.\n * @param {string} tableRowPreference The table row preference.\n * @param {string} tableSearchElement The table search element.\n * @param {string|null} tableId The table id.\n * @param {string|null} tableMethodName The table method name.\n */\nexport const init = (quiz,\n context,\n tableCardElement,\n tableElementId,\n tableFragmentValue,\n tableRowPreference,\n tableSearchElement,\n tableId = null,\n tableMethodName = null) => {\n quizId = quiz;\n contextId = context;\n cardElement = tableCardElement;\n elementId = tableElementId;\n fragmentValue = tableFragmentValue;\n rowPreference = tableRowPreference;\n searchElement = tableSearchElement;\n id = tableId;\n methodName = tableMethodName;\n };\n"],"names":["cardElement","contextId","elementId","fragmentValue","hoursFilter","rowPreference","sortValue","searchElement","id","methodName","quizId","overridden","getTable","quiz","hours","sortValueTable","page","search","document","getElementById","value","trim","tableElement","spinner","getElementsByClassName","tableBody","values","hoursahead","hoursbehind","sortArray","split","sortOn","direction","sorton","params","JSON","stringify","classList","remove","loadFragment","done","response","js","innerHTML","runTemplateJS","add","tableEventListeners","fail","exception","Error","debounceTable","Debouncer","debouncer","tableSort","event","preventDefault","linkUrl","URL","target","closest","href","targetSortBy","searchParams","get","targetSortOrder","call","methodname","args","tableid","preference","then","tableHide","hideArray","links","querySelectorAll","targetAction","targetColumn","action","column","indexOf","i","length","hideLinkUrl","tableReset","key","ctrlKey","tableSearchInputElement","focus","tagName","toLowerCase","rows","dataset","metric","UserPreference","setUserPreference","tableNav","element","sort","parentNode","getElementsByTagName","tableNavElement","tableCardElement","resetLink","overrideLinks","disabledLinks","addEventListener","triggerOverrideModal","forEach","navElement","userid","substring","includes","elements","pop","displayModalForm","context","tableElementId","tableFragmentValue","tableRowPreference","tableSearchElement","tableId","tableMethodName"],"mappings":"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"} \ No newline at end of file diff --git a/amd/build/user_preferences.min.js b/amd/build/user_preferences.min.js index 7294ec23..ab61f9b9 100644 --- a/amd/build/user_preferences.min.js +++ b/amd/build/user_preferences.min.js @@ -3,7 +3,6 @@ define("local_assessfreq/user_preferences",["exports","core/ajax","core/notifica * User preferences JS module. * * @module local_assessfreq/user_preferences - * @package local_assessfreq * @copyright 2020 Guillermo Gomez * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.setUserPreference=_exports.getUserPreference=void 0,_ajax=_interopRequireDefault(_ajax),_notification=_interopRequireDefault(_notification);_exports.setUserPreference=(type,value)=>{const request={methodname:"core_user_update_user_preferences",args:{preferences:[{type:type,value:value}]}};return _ajax.default.call([request])[0].fail((()=>{_notification.default.exception(new Error("Failed to update user preference"))}))};_exports.getUserPreference=name=>{const request={methodname:"core_user_get_user_preferences",args:{name:name}};return _ajax.default.call([request])[0]}})); diff --git a/amd/build/user_preferences.min.js.map b/amd/build/user_preferences.min.js.map index 1f5759f2..4806adb6 100644 --- a/amd/build/user_preferences.min.js.map +++ b/amd/build/user_preferences.min.js.map @@ -1 +1 @@ -{"version":3,"file":"user_preferences.min.js","sources":["../src/user_preferences.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\n/**\n * User preferences JS module.\n *\n * @module local_assessfreq/user_preferences\n * @package local_assessfreq\n * @copyright 2020 Guillermo Gomez \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\n\n/**\n * Generic handler to persist user preferences.\n *\n * @method setUserPreference\n * @param {string} type The name of the attribute you're updating\n * @param {string} value The value of the attribute you're updating\n * @return {promise} jQuery promise\n */\nexport const setUserPreference = (type, value) => {\n const request = {\n methodname: 'core_user_update_user_preferences',\n args: {\n preferences: [{type: type, value: value}]\n }\n };\n\n return Ajax.call([request])[0]\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference'));\n });\n};\n\n/**\n * Generic handler to get user preference.\n *\n * @method getUserPreference\n * @param {string} name The name of the attribute you're getting.\n * @return {promise} jQuery promise\n */\nexport const getUserPreference = (name) => {\n const request = {\n methodname: 'core_user_get_user_preferences',\n args: {\n 'name': name\n }\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["type","value","request","methodname","args","preferences","Ajax","call","fail","exception","Error","name"],"mappings":";;;;;;;;6OAmCiC,CAACA,KAAMC,eAC9BC,QAAU,CACZC,WAAY,oCACZC,KAAM,CACFC,YAAa,CAAC,CAACL,KAAMA,KAAMC,MAAOA,iBAInCK,cAAKC,KAAK,CAACL,UAAU,GAC3BM,MAAK,2BACWC,UAAU,IAAIC,MAAM,oEAWPC,aACxBT,QAAU,CACZC,WAAY,iCACZC,KAAM,MACMO,cAITL,cAAKC,KAAK,CAACL,UAAU"} \ No newline at end of file +{"version":3,"file":"user_preferences.min.js","sources":["../src/user_preferences.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\n/**\n * User preferences JS module.\n *\n * @module local_assessfreq/user_preferences\n * @copyright 2020 Guillermo Gomez \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\nimport Notification from 'core/notification';\n\n/**\n * Generic handler to persist user preferences.\n *\n * @method setUserPreference\n * @param {string} type The name of the attribute you're updating\n * @param {string} value The value of the attribute you're updating\n * @return {promise} jQuery promise\n */\nexport const setUserPreference = (type, value) => {\n const request = {\n methodname: 'core_user_update_user_preferences',\n args: {\n preferences: [{type: type, value: value}]\n }\n };\n\n return Ajax.call([request])[0]\n .fail(() => {\n Notification.exception(new Error('Failed to update user preference'));\n });\n};\n\n/**\n * Generic handler to get user preference.\n *\n * @method getUserPreference\n * @param {string} name The name of the attribute you're getting.\n * @return {promise} jQuery promise\n */\nexport const getUserPreference = (name) => {\n const request = {\n methodname: 'core_user_get_user_preferences',\n args: {\n 'name': name\n }\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["type","value","request","methodname","args","preferences","Ajax","call","fail","exception","Error","name"],"mappings":";;;;;;;6OAkCiC,CAACA,KAAMC,eAC9BC,QAAU,CACZC,WAAY,oCACZC,KAAM,CACFC,YAAa,CAAC,CAACL,KAAMA,KAAMC,MAAOA,iBAInCK,cAAKC,KAAK,CAACL,UAAU,GAC3BM,MAAK,2BACWC,UAAU,IAAIC,MAAM,oEAWPC,aACxBT,QAAU,CACZC,WAAY,iCACZC,KAAM,MACMO,cAITL,cAAKC,KAAK,CAACL,UAAU"} \ No newline at end of file diff --git a/amd/build/zoom_modal.min.js b/amd/build/zoom_modal.min.js index 32799469..952b3e04 100644 --- a/amd/build/zoom_modal.min.js +++ b/amd/build/zoom_modal.min.js @@ -1,10 +1,9 @@ /** * Javascript for report card display and processing. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("local_assessfreq/zoom_modal",["core/str","core/modal","core/fragment","core/ajax","core/templates","local_assessfreq/modal_large","core/notification"],(function(Str,Modal,Fragment,Ajax,Templates,ModalLarge,Notification){var contextid,modalObj,ZoomModal={};ZoomModal.zoomGraph=function(event,params,method){let title=event.target.parentElement.dataset.title;Fragment.loadFragment("local_assessfreq",method,contextid,params).done((response=>{let resObj=JSON.parse(response);if(1==resObj.hasdata){var context={withtable:!1,chartdata:JSON.stringify(resObj.chart),aspect:!1};return modalObj.setTitle(title),modalObj.setBody(Templates.render("local_assessfreq/chart",context)),void modalObj.show()}Str.get_string("nodata","local_assessfreq").then((str=>{const noDatastr=document.createElement("h3");noDatastr.innerHTML=str,modalObj.setTitle(title),modalObj.setBody(noDatastr.outerHTML),modalObj.show()})).catch((()=>{Notification.exception(new Error("Failed to load string: nodata"))}))})).fail((()=>{Notification.exception(new Error("Failed to load zoomed graph"))}))};return ZoomModal.init=function(context){contextid=context,new Promise(((resolve,reject)=>{Str.get_string("loading","core").then((title=>{Modal.create({type:ModalLarge.TYPE,title:title,body:'

',large:!0}).then((modal=>{modalObj=modal,resolve()}))})).catch(Notification.exception)}))},ZoomModal})); +define("local_assessfreq/zoom_modal",["core/str","core/modal","core/fragment","core/ajax","core/templates","local_assessfreq/modal_large","core/notification"],(function(Str,Modal,Fragment,Ajax,Templates,ModalLarge,Notification){var contextid,modalObj,ZoomModal={};ZoomModal.zoomGraph=function(event,params,method){let title=event.target.parentElement.dataset.title;Fragment.loadFragment("local_assessfreq",method,contextid,params).done((response=>{let resObj=JSON.parse(response);if(1==resObj.hasdata){var context={withtable:!1,chartdata:JSON.stringify(resObj.chart),aspect:!1};return modalObj.setTitle(title),modalObj.setBody(Templates.render("local_assessfreq/chart",context)),void modalObj.show()}Str.get_string("nodata","local_assessfreq").then((str=>{const noDatastr=document.createElement("h3");noDatastr.innerHTML=str,modalObj.setTitle(title),modalObj.setBody(noDatastr.outerHTML),modalObj.show()})).catch((()=>{Notification.exception(new Error("Failed to load string: nodata"))}))})).fail((()=>{Notification.exception(new Error("Failed to load zoomed graph"))}))};return ZoomModal.init=function(context){contextid=context,new Promise((resolve=>{Str.get_string("loading","core").then((title=>{Modal.create({type:ModalLarge.TYPE,title:title,body:'

',large:!0}).then((modal=>{modalObj=modal,resolve()}))})).catch(Notification.exception)}))},ZoomModal})); //# sourceMappingURL=zoom_modal.min.js.map \ No newline at end of file diff --git a/amd/build/zoom_modal.min.js.map b/amd/build/zoom_modal.min.js.map index 9f27ed51..bf129277 100644 --- a/amd/build/zoom_modal.min.js.map +++ b/amd/build/zoom_modal.min.js.map @@ -1 +1 @@ -{"version":3,"file":"zoom_modal.min.js","sources":["../src/zoom_modal.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\n/**\n * Javascript for report card display and processing.\n *\n * @package local_assessfreq\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['core/str', 'core/modal', 'core/fragment', 'core/ajax', 'core/templates', 'local_assessfreq/modal_large',\n 'core/notification'],\n function (Str, Modal, Fragment, Ajax, Templates, ModalLarge, Notification) {\n\n /**\n * Module level variables.\n */\n var ZoomModal = {};\n var contextid;\n var modalObj;\n const spinner = '

'\n + ''\n + '

';\n\n /**\n * Provides zoom functionality for card graphs.\n */\n ZoomModal.zoomGraph = function (event, params, method) {\n let title = event.target.parentElement.dataset.title;\n\n Fragment.loadFragment('local_assessfreq', method, contextid, params)\n .done((response) => {\n let resObj = JSON.parse(response);\n if (resObj.hasdata == true) {\n var context = { 'withtable' : false, 'chartdata' : JSON.stringify(resObj.chart), aspect: false};\n modalObj.setTitle(title);\n modalObj.setBody(Templates.render('local_assessfreq/chart', context));\n modalObj.show();\n return;\n } else {\n Str.get_string('nodata', 'local_assessfreq').then((str) => {\n const noDatastr = document.createElement('h3');\n noDatastr.innerHTML = str;\n modalObj.setTitle(title);\n modalObj.setBody(noDatastr.outerHTML);\n modalObj.show();\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: nodata'));\n });\n }\n }).fail(() => {\n Notification.exception(new Error('Failed to load zoomed graph'));\n return;\n });\n\n };\n\n /**\n * Create the modal window for graph zooming.\n *\n * @private\n */\n const createModal = function () {\n return new Promise((resolve, reject) => {\n Str.get_string('loading', 'core').then((title) => {\n // Create the Modal.\n Modal.create({\n type: ModalLarge.TYPE,\n title: title,\n body: spinner,\n large: true\n })\n .then((modal) => {\n modalObj = modal;\n resolve();\n });\n }).catch(Notification.exception);\n });\n };\n\n /**\n * Initialise method for quiz dashboard rendering.\n */\n ZoomModal.init = function (context) {\n contextid = context;\n createModal();\n };\n\n return ZoomModal;\n }\n);\n"],"names":["define","Str","Modal","Fragment","Ajax","Templates","ModalLarge","Notification","contextid","modalObj","ZoomModal","zoomGraph","event","params","method","title","target","parentElement","dataset","loadFragment","done","response","resObj","JSON","parse","hasdata","context","stringify","chart","aspect","setTitle","setBody","render","show","get_string","then","str","noDatastr","document","createElement","innerHTML","outerHTML","catch","exception","Error","fail","init","Promise","resolve","reject","create","type","TYPE","body","large","modal"],"mappings":";;;;;;;AAuBAA,qCACI,CAAC,WAAY,aAAc,gBAAiB,YAAa,iBAAkB,+BAC3E,sBACA,SAAUC,IAAKC,MAAOC,SAAUC,KAAMC,UAAWC,WAAYC,kBAMrDC,UACAC,SAFAC,UAAY,GAUhBA,UAAUC,UAAY,SAAUC,MAAOC,OAAQC,YACvCC,MAAQH,MAAMI,OAAOC,cAAcC,QAAQH,MAE/CZ,SAASgB,aAAa,mBAAoBL,OAAQN,UAAWK,QAC5DO,MAAMC,eACCC,OAASC,KAAKC,MAAMH,aACF,GAAlBC,OAAOG,QAAiB,KACpBC,QAAU,YAAgB,YAAqBH,KAAKI,UAAUL,OAAOM,OAAQC,QAAQ,UACzFpB,SAASqB,SAASf,OAClBN,SAASsB,QAAQ1B,UAAU2B,OAAO,yBAA0BN,eAC5DjB,SAASwB,OAGThC,IAAIiC,WAAW,SAAU,oBAAoBC,MAAMC,YACzCC,UAAYC,SAASC,cAAc,MACzCF,UAAUG,UAAYJ,IACtB3B,SAASqB,SAASf,OAClBN,SAASsB,QAAQM,UAAUI,WAC3BhC,SAASwB,UAEVS,OAAM,KACLnC,aAAaoC,UAAU,IAAIC,MAAM,wCAG1CC,MAAK,KACJtC,aAAaoC,UAAU,IAAIC,MAAM,2CAgCzClC,UAAUoC,KAAO,SAAUpB,SACvBlB,UAAYkB,QArBL,IAAIqB,SAAQ,CAACC,QAASC,UACzBhD,IAAIiC,WAAW,UAAW,QAAQC,MAAMpB,QAEpCb,MAAMgD,OAAO,CACTC,KAAM7C,WAAW8C,KACjBrC,MAAOA,MACPsC,KAlDA,sFAmDAC,OAAO,IAEVnB,MAAMoB,QACH9C,SAAW8C,MACXP,gBAELN,MAAMnC,aAAaoC,eAYvBjC"} \ No newline at end of file +{"version":3,"file":"zoom_modal.min.js","sources":["../src/zoom_modal.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\n/**\n * Javascript for report card display and processing.\n *\n * @copyright 2020 Matt Porritt \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n ['core/str', 'core/modal', 'core/fragment', 'core/ajax', 'core/templates', 'local_assessfreq/modal_large',\n 'core/notification'],\n function (Str, Modal, Fragment, Ajax, Templates, ModalLarge, Notification) {\n\n /**\n * Module level variables.\n */\n var ZoomModal = {};\n var contextid;\n var modalObj;\n const spinner = '

'\n + ''\n + '

';\n\n /**\n * Provides zoom functionality for card graphs.\n *\n * @param {object} event The event object.\n * @param {object} params The parameters for the fragment call.\n * @param {string} method The method to call in the fragment.\n */\n ZoomModal.zoomGraph = function (event, params, method) {\n let title = event.target.parentElement.dataset.title;\n\n Fragment.loadFragment('local_assessfreq', method, contextid, params)\n .done((response) => {\n let resObj = JSON.parse(response);\n if (resObj.hasdata == true) {\n var context = { 'withtable' : false, 'chartdata' : JSON.stringify(resObj.chart), aspect: false};\n modalObj.setTitle(title);\n modalObj.setBody(Templates.render('local_assessfreq/chart', context));\n modalObj.show();\n return;\n } else {\n Str.get_string('nodata', 'local_assessfreq').then((str) => {\n const noDatastr = document.createElement('h3');\n noDatastr.innerHTML = str;\n modalObj.setTitle(title);\n modalObj.setBody(noDatastr.outerHTML);\n modalObj.show();\n return;\n }).catch(() => {\n Notification.exception(new Error('Failed to load string: nodata'));\n });\n }\n }).fail(() => {\n Notification.exception(new Error('Failed to load zoomed graph'));\n return;\n });\n\n };\n\n /**\n * Create the modal window for graph zooming.\n *\n * @private\n */\n const createModal = function () {\n return new Promise((resolve) => {\n Str.get_string('loading', 'core').then((title) => {\n // Create the Modal.\n Modal.create({\n type: ModalLarge.TYPE,\n title: title,\n body: spinner,\n large: true\n })\n .then((modal) => {\n modalObj = modal;\n resolve();\n });\n }).catch(Notification.exception);\n });\n };\n\n /**\n * Initialise method for quiz dashboard rendering.\n *\n * @param {int} context The context id for the dashboard.\n */\n ZoomModal.init = function (context) {\n contextid = context;\n createModal();\n };\n\n return ZoomModal;\n }\n);\n"],"names":["define","Str","Modal","Fragment","Ajax","Templates","ModalLarge","Notification","contextid","modalObj","ZoomModal","zoomGraph","event","params","method","title","target","parentElement","dataset","loadFragment","done","response","resObj","JSON","parse","hasdata","context","stringify","chart","aspect","setTitle","setBody","render","show","get_string","then","str","noDatastr","document","createElement","innerHTML","outerHTML","catch","exception","Error","fail","init","Promise","resolve","create","type","TYPE","body","large","modal"],"mappings":";;;;;;AAsBAA,qCACI,CAAC,WAAY,aAAc,gBAAiB,YAAa,iBAAkB,+BAC3E,sBACA,SAAUC,IAAKC,MAAOC,SAAUC,KAAMC,UAAWC,WAAYC,kBAMrDC,UACAC,SAFAC,UAAY,GAchBA,UAAUC,UAAY,SAAUC,MAAOC,OAAQC,YACvCC,MAAQH,MAAMI,OAAOC,cAAcC,QAAQH,MAE/CZ,SAASgB,aAAa,mBAAoBL,OAAQN,UAAWK,QAC5DO,MAAMC,eACCC,OAASC,KAAKC,MAAMH,aACF,GAAlBC,OAAOG,QAAiB,KACpBC,QAAU,YAAgB,YAAqBH,KAAKI,UAAUL,OAAOM,OAAQC,QAAQ,UACzFpB,SAASqB,SAASf,OAClBN,SAASsB,QAAQ1B,UAAU2B,OAAO,yBAA0BN,eAC5DjB,SAASwB,OAGThC,IAAIiC,WAAW,SAAU,oBAAoBC,MAAMC,YACzCC,UAAYC,SAASC,cAAc,MACzCF,UAAUG,UAAYJ,IACtB3B,SAASqB,SAASf,OAClBN,SAASsB,QAAQM,UAAUI,WAC3BhC,SAASwB,UAEVS,OAAM,KACLnC,aAAaoC,UAAU,IAAIC,MAAM,wCAG1CC,MAAK,KACJtC,aAAaoC,UAAU,IAAIC,MAAM,2CAkCzClC,UAAUoC,KAAO,SAAUpB,SACvBlB,UAAYkB,QAvBL,IAAIqB,SAASC,UAChB/C,IAAIiC,WAAW,UAAW,QAAQC,MAAMpB,QAEpCb,MAAM+C,OAAO,CACTC,KAAM5C,WAAW6C,KACjBpC,MAAOA,MACPqC,KAtDA,sFAuDAC,OAAO,IAEVlB,MAAMmB,QACH7C,SAAW6C,MACXN,gBAELN,MAAMnC,aAAaoC,eAcvBjC"} \ No newline at end of file diff --git a/amd/src/calendar.js b/amd/src/calendar.js index 5c0de108..726a0259 100644 --- a/amd/src/calendar.js +++ b/amd/src/calendar.js @@ -16,7 +16,6 @@ /** * Javascript for heatmap calendar generation and display. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -59,7 +58,7 @@ define(['core/str', 'core/notification', 'core/ajax'], function (Str, Notificati /** * Pick a contrasting text color based on the background color. * - * @param {String} A hexcolor value. + * @param {String} hexcolor A hexcolor value. * @return {String} The contrasting color (black or white). */ const getContrast = function (hexcolor) { @@ -218,9 +217,12 @@ define(['core/str', 'core/notification', 'core/ajax'], function (Str, Notificati * Get the events to display in the calendar via ajax call. * * @method getEvents - * @param {Number} year The year to get the events for. - * @param {String} metric The type of metric to get, 'students' or 'assess'. - * @param {Array} modules Array of the modules to get. + * + * @param {Object} args The arguments to pass to the ajax call. + * @param {Number} args.year The year to get the events for. + * @param {String} args.metric The metric to get the events for. + * @param {Array} args.modules The modules to get the events for. + * * @return {Promise} */ const getEvents = function ({year, metric, modules}) { @@ -267,9 +269,11 @@ define(['core/str', 'core/notification', 'core/ajax'], function (Str, Notificati /** * Create the table structure for the calendar months. * - * @oaram {Number} year The year to generate the tables for. - * @param {Number} startMonth The month to start table generation from. - * @param {Number} endMonth The month to generate the tables to. + * @param {Object} args The arguments to pass to the ajax call. + * @param {Number} args.year The year to get the events for. + * @param {Number} args.startMonth The month to start the calendar + * @param {Number} args.endMonth The month to end the calendar + * * @return {Promise} */ const createTables = function ({year, startMonth, endMonth}) { @@ -403,9 +407,11 @@ define(['core/str', 'core/notification', 'core/ajax'], function (Str, Notificati /** * Controls the population of the calendar in to the base tables. * - * @param {Object} calendarContainer the container to populate. - * @param {Number} year The year to generate calendar for. - * @param {Number} startMonth The month to start generation from. + * @param {Object} args The arguments to pass to the ajax call. + * @param {Object} args.calendarContainer The container to populate the calendar into. + * @param {Number} args.year The year to get the events for. + * @param {Number} args.startMonth The month to start the calendar + * * @return {Promise} */ const populateCalendar = function ({calendarContainer, year, startMonth}) { diff --git a/amd/src/chart_data.js b/amd/src/chart_data.js index c66a818d..3587f213 100644 --- a/amd/src/chart_data.js +++ b/amd/src/chart_data.js @@ -17,7 +17,6 @@ * Chart data JS module. * * @module local_assessfreq/char_data - * @package local_assessfreq * @copyright 2020 Guillermo Gomez * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/src/chart_output_chartjs.js b/amd/src/chart_output_chartjs.js index 4cc3039c..5f0f1439 100644 --- a/amd/src/chart_output_chartjs.js +++ b/amd/src/chart_output_chartjs.js @@ -16,7 +16,6 @@ /** * Chart output for chart.js with custom override for aspect config. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -33,7 +32,6 @@ define(['core/chart_output_chartjs'], function (Output) { * Overrride the config. * * @protected - * @param {module:core/chart_axis} axis The axis. * @return {Object} The axis config. */ Output.prototype._makeConfig = function () { @@ -103,6 +101,11 @@ define(['core/chart_output_chartjs'], function (Output) { /** * Get the aspect ratio setting and initialise the chart. + * + * @param {string} chartImage The image to replace. + * @param {object} ChartInst The chart instance. + * @param {boolean} aspect The aspect ratio. + * @param {object} legend The legend options. */ ChartOutput.init = function (chartImage, ChartInst, aspect, legend) { aspectRatio = aspect; diff --git a/amd/src/dashboard_assessment.js b/amd/src/dashboard_assessment.js index 6ecaacea..144087a0 100644 --- a/amd/src/dashboard_assessment.js +++ b/amd/src/dashboard_assessment.js @@ -17,7 +17,6 @@ * Javascript for report card display and processing. * * @module local_assessfreq/dashboard_assessment - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/src/dashboard_quiz.js b/amd/src/dashboard_quiz.js index 6a036bfb..41d6ed45 100644 --- a/amd/src/dashboard_quiz.js +++ b/amd/src/dashboard_quiz.js @@ -17,7 +17,6 @@ * Javascript for report card display and processing. * * @module local_assessfreq/dashboard_quiz - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/src/dashboard_quiz_inprogress.js b/amd/src/dashboard_quiz_inprogress.js index 4d465d89..674f7049 100644 --- a/amd/src/dashboard_quiz_inprogress.js +++ b/amd/src/dashboard_quiz_inprogress.js @@ -17,7 +17,6 @@ * Javascript for quizzes in progress display and processing. * * @module local_assessfreq/dashboard_quiz_inprogress - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/src/dayview.js b/amd/src/dayview.js index 6d80b6f0..2dbfaaed 100644 --- a/amd/src/dayview.js +++ b/amd/src/dayview.js @@ -16,7 +16,6 @@ /** * Javascript for heatmap calendar generation and display. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -130,6 +129,8 @@ define( /** * Initialise the base modal to be used. * + * @param {int} date The date to display the day view for. + * */ Dayview.display = function (date) { modalObj.setBody(spinner); @@ -163,7 +164,6 @@ define( /** * Initialise the base modal to be used. * - * @param {integer} context The current context id. */ Dayview.init = function () { // Load the strings we'll need later. diff --git a/amd/src/debouncer.js b/amd/src/debouncer.js index b1874d6e..6e0f35ba 100644 --- a/amd/src/debouncer.js +++ b/amd/src/debouncer.js @@ -17,7 +17,6 @@ * Debounce JS module. * * @module local_assessfreq/debouncer - * @package local_assessfreq * @copyright 2020 Guillermo Gomez * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * diff --git a/amd/src/form_modal.js b/amd/src/form_modal.js index 98d1cf35..5d2f6dc4 100644 --- a/amd/src/form_modal.js +++ b/amd/src/form_modal.js @@ -16,14 +16,13 @@ /** * Javascript for report card display and processing. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define( - ['core/str', 'core/modal', 'core/fragment', 'core/ajax'], - function (Str, Modal, Fragment, Ajax) { + ['core/str', 'core/modal', 'core/fragment', 'core/ajax', 'core/notification'], + function (Str, Modal, Fragment, Ajax, Notification) { /** * Module level variables. @@ -224,6 +223,10 @@ define( /** * Initialise method for quiz dashboard rendering. + * + * @param {int} context The context id for the dashboard. + * @param {function} processDashboard The callback function to process the dashboard. + * */ FormModal.init = function (context, processDashboard) { contextid = context; diff --git a/amd/src/modal_large.js b/amd/src/modal_large.js index 4ba79b6f..f00fc33e 100644 --- a/amd/src/modal_large.js +++ b/amd/src/modal_large.js @@ -16,7 +16,6 @@ /** * Javascript for large modal . * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/src/override_modal.js b/amd/src/override_modal.js index 87d5a7c0..23be45b4 100644 --- a/amd/src/override_modal.js +++ b/amd/src/override_modal.js @@ -16,14 +16,13 @@ /** * Javascript for report card display and processing. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define( - ['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/fragment', 'core/ajax'], - function ($,Str, Modal, ModalEvents, Fragment, Ajax) { + ['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/fragment', 'core/ajax', 'core/notification'], + function ($,Str, Modal, ModalEvents, Fragment, Ajax, Notification) { /** * Module level variables. @@ -73,8 +72,9 @@ define( /** * Updates the body of the modal window. * - * @param {Object} formdata - * @private + * @param {int} quiz The quiz id. + * @param {int} user The user id. + * @param {object} formdata The form data. */ const updateModalBody = function (quiz, user, formdata) { if (typeof formdata === "undefined") { @@ -146,6 +146,10 @@ define( /** * Display the Modal form. + * + * @param {int} quiz The quiz id. + * @param {int} user The user id. + * @param {int} hours The hours to filter the quiz by. */ OverrideModal.displayModalForm = function (quiz, user, hours = null) { quizid = quiz; @@ -157,6 +161,10 @@ define( /** * Initialise method for quiz dashboard rendering. + * + * @param {int} context The context id for the dashboard. + * @param {function} callbackFunction The callback function to call after the modal is closed. + * @param {int} hours The hours to filter the quiz by. */ OverrideModal.init = function (context, callbackFunction, hours = null) { contextid = context; diff --git a/amd/src/student_search.js b/amd/src/student_search.js index e0c80aa9..6bbe09a3 100644 --- a/amd/src/student_search.js +++ b/amd/src/student_search.js @@ -17,7 +17,6 @@ * Javascript for student search display and processing. * * @module local_assessfreq/student_search - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/src/summary_participants.js b/amd/src/summary_participants.js index 3182a805..8d036b68 100644 --- a/amd/src/summary_participants.js +++ b/amd/src/summary_participants.js @@ -16,7 +16,6 @@ /** * Javascript for summary participants graph. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/src/table_handler.js b/amd/src/table_handler.js index 3e713a7f..86a144c0 100644 --- a/amd/src/table_handler.js +++ b/amd/src/table_handler.js @@ -17,7 +17,6 @@ * Table handler JS module. * * @module local_assessfreq/table_handler - * @package local_assessfreq * @copyright 2020 Guillermo Gomez * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -239,6 +238,8 @@ const tableReset = (event) => { /** * Process the search events from the student table. * + * @param {Event} event The triggered event for the element. + * */ export const tableSearch = (event) => { if (event.key === 'Meta' || event.ctrlKey) { diff --git a/amd/src/user_preferences.js b/amd/src/user_preferences.js index fe2ca89c..7d18bd28 100644 --- a/amd/src/user_preferences.js +++ b/amd/src/user_preferences.js @@ -17,7 +17,6 @@ * User preferences JS module. * * @module local_assessfreq/user_preferences - * @package local_assessfreq * @copyright 2020 Guillermo Gomez * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/amd/src/zoom_modal.js b/amd/src/zoom_modal.js index b48d193c..c1ea2366 100644 --- a/amd/src/zoom_modal.js +++ b/amd/src/zoom_modal.js @@ -16,7 +16,6 @@ /** * Javascript for report card display and processing. * - * @package local_assessfreq * @copyright 2020 Matt Porritt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -38,6 +37,10 @@ define( /** * Provides zoom functionality for card graphs. + * + * @param {object} event The event object. + * @param {object} params The parameters for the fragment call. + * @param {string} method The method to call in the fragment. */ ZoomModal.zoomGraph = function (event, params, method) { let title = event.target.parentElement.dataset.title; @@ -76,7 +79,7 @@ define( * @private */ const createModal = function () { - return new Promise((resolve, reject) => { + return new Promise((resolve) => { Str.get_string('loading', 'core').then((title) => { // Create the Modal. Modal.create({ @@ -95,6 +98,8 @@ define( /** * Initialise method for quiz dashboard rendering. + * + * @param {int} context The context id for the dashboard. */ ZoomModal.init = function (context) { contextid = context;