From 8c05930e7e64574e74a8373c64e89ee3bd78e925 Mon Sep 17 00:00:00 2001 From: AllanVester Date: Mon, 25 Nov 2024 15:55:08 +0100 Subject: [PATCH 1/6] Not quite working yet --- .../homework/amd/build/clickInfo.min.js | 2 +- .../homework/amd/build/clickInfo.min.js.map | 2 +- .../homework/amd/build/clickStats.min.js | 11 ++ .../homework/amd/build/clickStats.min.js.map | 1 + .../blocks/homework/amd/src/clickInfo.js | 16 +-- .../blocks/homework/amd/src/clickStats.js | 55 +++++++ .../moodle/blocks/homework/block_homework.php | 1 + .../classes/external/get_stats_modal.php | 135 ++++++++++++++++++ server/moodle/blocks/homework/db/services.php | 20 ++- .../blocks/homework/templates/data.mustache | 2 +- .../blocks/homework/templates/stats.mustache | 9 ++ server/moodle/blocks/homework/version.php | 2 +- 12 files changed, 236 insertions(+), 20 deletions(-) create mode 100644 server/moodle/blocks/homework/amd/build/clickStats.min.js create mode 100644 server/moodle/blocks/homework/amd/build/clickStats.min.js.map create mode 100644 server/moodle/blocks/homework/amd/src/clickStats.js create mode 100644 server/moodle/blocks/homework/classes/external/get_stats_modal.php create mode 100644 server/moodle/blocks/homework/templates/stats.mustache diff --git a/server/moodle/blocks/homework/amd/build/clickInfo.min.js b/server/moodle/blocks/homework/amd/build/clickInfo.min.js index 780f3d18..94e0b72d 100644 --- a/server/moodle/blocks/homework/amd/build/clickInfo.min.js +++ b/server/moodle/blocks/homework/amd/build/clickInfo.min.js @@ -6,6 +6,6 @@ define("block_homework/clickInfo",["exports","jquery","core/ajax","block_homewor * @copyright 2024, cs-24-sw-5-01 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_ajax=_interopRequireDefault(_ajax),_modals=_interopRequireDefault(_modals);_exports.init=async userID=>{(0,_jquery.default)(document).ready((function(){(0,_jquery.default)(".timebutton").on("click",(e=>{_ajax.default.call([{methodname:"block_homework_get_infohomework_modal",args:{homeworkID:e.target.id},done:async function(response){const modal=await _modals.default.create({title:""+response.course+": "+response.title+" | "+response.duedate,body:`${response.html}`,large:!0,removeOnClose:!0});await modal.show(),modal.getRoot().on("click",'[data-action="submit"]',(e=>{e.preventDefault(),handleFormSubmit(userID,modal)})),modal.getRoot().on("click",'[data-action="cancel"]',(e=>{e.preventDefault(),modal.destroy()}))},fail:error=>{throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`)}}])}))}))};const handleFormSubmit=(userID,modal)=>{let literatureInputFields=document.querySelectorAll(".homework-time-literature"),linksInputFields=document.querySelectorAll(".homework-time-links"),videosInputFields=document.querySelectorAll(".homework-time-videos"),timeData1=[],timeData2=[],timeData3=[];for(let inputField of literatureInputFields)""!==inputField.value&&timeData1.push({id:inputField.id,time:inputField.value});for(let inputField of linksInputFields)""!==inputField.value&&timeData2.push({id:inputField.id,time:inputField.value});for(let inputField of videosInputFields)""!==inputField.value&&timeData3.push({id:inputField.id,time:inputField.value});timeData1.length||timeData2.length||timeData3.length?_ajax.default.call([{methodname:"block_homework_save_homeworktime",args:{user:userID,timeCompletedLiterature:timeData1,timeCompletedLinks:timeData2,timeCompletedVideos:timeData3},done:function(){modal.destroy(),location.reload()},fail:function(error){console.error("Failed to save data:",error)}}]):modal.destroy()}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_ajax=_interopRequireDefault(_ajax),_modals=_interopRequireDefault(_modals);_exports.init=async userID=>{(0,_jquery.default)(document).ready((function(){(0,_jquery.default)(".timebutton").on("click",(e=>{_ajax.default.call([{methodname:"block_homework_get_infohomework_modal",args:{homeworkID:e.target.id},done:async function(response){const modal=await _modals.default.create({title:""+response.course+": "+response.title+" | "+response.duedate,body:`${response.html}`,large:!0,removeOnClose:!0});await modal.show(),modal.getRoot().on("click",'[data-action="submit"]',(e=>{e.preventDefault(),handleFormSubmit(userID,modal)})),modal.getRoot().on("click",'[data-action="cancel"]',(e=>{e.preventDefault(),modal.destroy()}))},fail:error=>{throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`)}}])}))}))};const handleFormSubmit=(userID,modal)=>{let literatureInputFields=document.querySelectorAll(".homework-time-literature"),linksInputFields=document.querySelectorAll(".homework-time-links"),videosInputFields=document.querySelectorAll(".homework-time-videos"),timeData=[];for(let inputField of literatureInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});for(let inputField of linksInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});for(let inputField of videosInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});timeData.length?_ajax.default.call([{methodname:"block_homework_save_homeworktime",args:{user:userID,timeCompleted:timeData},done:function(){modal.destroy(),location.reload()},fail:function(error){console.error("Failed to save data:",error)}}]):modal.destroy()}})); //# sourceMappingURL=clickInfo.min.js.map \ No newline at end of file diff --git a/server/moodle/blocks/homework/amd/build/clickInfo.min.js.map b/server/moodle/blocks/homework/amd/build/clickInfo.min.js.map index 8fb4677c..c5cee162 100644 --- a/server/moodle/blocks/homework/amd/build/clickInfo.min.js.map +++ b/server/moodle/blocks/homework/amd/build/clickInfo.min.js.map @@ -1 +1 @@ -{"version":3,"file":"clickInfo.min.js","sources":["../src/clickInfo.js"],"sourcesContent":["import $ from 'jquery';\nimport Ajax from 'core/ajax';\nimport MyModal from 'block_homework/modals';\n\n/**\n * Homework/amd/src/modal_homework.js\n *\n * @package\n * @copyright 2024, cs-24-sw-5-01 \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n\n/**\n * Fetches and initializes the completion modal for the homework module that was clicked on.\n * @param userID ID of currently logged-in user.\n * @returns {Promise} A promise that, when fulfilled, opens the modal\n */\nexport const init = async(userID) => {\n // Create the modal using block_homework_get_infohomework_modal\n $(document).ready(function() {\n $('.timebutton').on('click', (e) => {\n Ajax.call([{\n methodname: 'block_homework_get_infohomework_modal',\n args: {\n homeworkID: e.target.id,\n },\n done: async function(response) {\n const modal = await MyModal.create({\n // eslint-disable-next-line max-len\n title: \"\" + response.course + \": \" + response.title + \" | \" + response.duedate,\n body: `${response.html}`,\n large: true,\n removeOnClose: true,\n });\n // Show the modal.\n await modal.show();\n\n // Attach event listeners for buttons\n modal.getRoot().on('click', '[data-action=\"submit\"]', (e) => {\n e.preventDefault();\n handleFormSubmit(userID, modal);\n });\n\n modal.getRoot().on('click', '[data-action=\"cancel\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n },\n fail: (error) => {\n throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`);\n }\n }]);\n });\n });\n};\n\n/**\n * Handle clicking the submit button of the form and updating the database with completion and times\n * @param userID ID of currently logged-in user\n * @param modal The modal that is being submitted\n */\nconst handleFormSubmit = (userID, modal) => {\n let literatureInputFields = document.querySelectorAll('.homework-time-literature');\n let linksInputFields = document.querySelectorAll('.homework-time-links');\n let videosInputFields = document.querySelectorAll('.homework-time-videos');\n let timeData1 = [];\n let timeData2 = [];\n let timeData3 = [];\n // Finds the data of all input fields, both literature, link and video, and adds the ID and time to an array.\n for (let inputField of literatureInputFields) {\n if (inputField.value !== \"\") {\n timeData1.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n for (let inputField of linksInputFields) {\n if (inputField.value !== \"\") {\n timeData2.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n for (let inputField of videosInputFields) {\n if (inputField.value !== \"\") {\n timeData3.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n\n // If no data has been filled, do nothing.\n if (!timeData1.length && !timeData2.length && !timeData3.length) {\n modal.destroy();\n return;\n }\n\n // If data has been filled, call block_homework_save_homeworktime with the user ID and data\n Ajax.call([{\n methodname: 'block_homework_save_homeworktime', // Your PHP function that will handle the data\n args: {\n user: userID,\n timeCompletedLiterature: timeData1,\n timeCompletedLinks: timeData2,\n timeCompletedVideos: timeData3,\n },\n done: function() {\n // Close the modal after successful submission\n modal.destroy();\n location.reload();\n },\n fail: function(error) {\n console.error(\"Failed to save data:\", error);\n }\n }]);\n};\n"],"names":["_interopRequireDefault","e","__esModule","default","_jquery","_ajax","_modals","_exports","init","async","$","document","ready","on","Ajax","call","methodname","args","homeworkID","target","id","done","response","modal","MyModal","create","title","courseurl","course","homeworkurl","duedate","body","html","large","removeOnClose","show","getRoot","preventDefault","handleFormSubmit","userID","destroy","fail","error","Error","JSON","stringify","literatureInputFields","querySelectorAll","linksInputFields","videosInputFields","timeData1","timeData2","timeData3","inputField","value","push","time","length","user","timeCompletedLiterature","timeCompletedLinks","timeCompletedVideos","location","reload","console"],"mappings":"qIAE4C,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;;kFAF5CG,QAAAJ,uBAAAI,SACAC,MAAAL,uBAAAK,OACAC,QAAAN,uBAAAM,SAsDEC,SAAAC,KArCkBC,gBAEhB,EAAAC,iBAAEC,UAAUC,OAAM,YACd,EAAAF,QAAAA,SAAE,eAAeG,GAAG,SAAUZ,IAC1Ba,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CACFC,WAAYjB,EAAEkB,OAAOC,IAEzBC,KAAMZ,eAAea,UACjB,MAAMC,YAAcC,QAAOrB,QAACsB,OAAO,CAE/BC,MAAO,YAAcJ,SAASK,UAAY,KAAOL,SAASM,OAAS,kBAAoBN,SAASO,YAAc,KAAOP,SAASI,MAAQ,UAAYJ,SAASQ,QAC3JC,KAAM,GAAGT,SAASU,OAClBC,OAAO,EACPC,eAAe,UAGbX,MAAMY,OAGZZ,MAAMa,UAAUvB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAEoC,iBACFC,iBAAiBC,OAAQhB,MAAM,IAGnCA,MAAMa,UAAUvB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAEoC,iBACFd,MAAMiB,SAAS,GAEtB,EACDC,KAAOC,QACH,MAAM,IAAIC,MAAM,yCAAyCC,KAAKC,UAAUH,SAAS,IAEtF,GAEX,GAAE,EAQN,MAAMJ,iBAAmBA,CAACC,OAAQhB,SAC9B,IAAIuB,sBAAwBnC,SAASoC,iBAAiB,6BAClDC,iBAAmBrC,SAASoC,iBAAiB,wBAC7CE,kBAAoBtC,SAASoC,iBAAiB,yBAC9CG,UAAY,GACZC,UAAY,GACZC,UAAY,GAEhB,IAAK,IAAIC,cAAcP,sBACM,KAArBO,WAAWC,OACXJ,UAAUK,KAAK,CACXnC,GAAIiC,WAAWjC,GACfoC,KAAMH,WAAWC,QAI7B,IAAK,IAAID,cAAcL,iBACM,KAArBK,WAAWC,OACXH,UAAUI,KAAK,CACXnC,GAAIiC,WAAWjC,GACfoC,KAAMH,WAAWC,QAI7B,IAAK,IAAID,cAAcJ,kBACM,KAArBI,WAAWC,OACXF,UAAUG,KAAK,CACXnC,GAAIiC,WAAWjC,GACfoC,KAAMH,WAAWC,QAMxBJ,UAAUO,QAAWN,UAAUM,QAAWL,UAAUK,OAMzD3C,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,mCACZC,KAAM,CACFyC,KAAMnB,OACNoB,wBAAyBT,UACzBU,mBAAoBT,UACpBU,oBAAqBT,WAEzB/B,KAAM,WAEFE,MAAMiB,UACNsB,SAASC,QACZ,EACDtB,KAAM,SAASC,OACXsB,QAAQtB,MAAM,uBAAwBA,MAC1C,KApBAnB,MAAMiB,SAqBP,CACL"} \ No newline at end of file +{"version":3,"file":"clickInfo.min.js","sources":["../src/clickInfo.js"],"sourcesContent":["import $ from 'jquery';\nimport Ajax from 'core/ajax';\nimport MyModal from 'block_homework/modals';\n\n/**\n * Homework/amd/src/modal_homework.js\n *\n * @package\n * @copyright 2024, cs-24-sw-5-01 \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n\n/**\n * Fetches and initializes the completion modal for the homework module that was clicked on.\n * @param userID ID of currently logged-in user.\n * @returns {Promise} A promise that, when fulfilled, opens the modal\n */\nexport const init = async(userID) => {\n // Create the modal using block_homework_get_infohomework_modal\n $(document).ready(function() {\n $('.timebutton').on('click', (e) => {\n Ajax.call([{\n methodname: 'block_homework_get_infohomework_modal',\n args: {\n homeworkID: e.target.id,\n },\n done: async function(response) {\n const modal = await MyModal.create({\n // eslint-disable-next-line max-len\n title: \"\" + response.course + \": \" + response.title + \" | \" + response.duedate,\n body: `${response.html}`,\n large: true,\n removeOnClose: true,\n });\n // Show the modal.\n await modal.show();\n\n // Attach event listeners for buttons\n modal.getRoot().on('click', '[data-action=\"submit\"]', (e) => {\n e.preventDefault();\n handleFormSubmit(userID, modal);\n });\n\n modal.getRoot().on('click', '[data-action=\"cancel\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n },\n fail: (error) => {\n throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`);\n }\n }]);\n });\n });\n};\n\n/**\n * Handle clicking the submit button of the form and updating the database with completion and times\n * @param userID ID of currently logged-in user\n * @param modal The modal that is being submitted\n */\nconst handleFormSubmit = (userID, modal) => {\n let literatureInputFields = document.querySelectorAll('.homework-time-literature');\n let linksInputFields = document.querySelectorAll('.homework-time-links');\n let videosInputFields = document.querySelectorAll('.homework-time-videos');\n let timeData = []\n // Finds the data of all input fields, both literature, link and video, and adds the ID and time to an array.\n for (let inputField of literatureInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n for (let inputField of linksInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n for (let inputField of videosInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n\n // If no data has been filled, do nothing.\n if (!timeData.length) {\n modal.destroy();\n return;\n }\n\n // If data has been filled, call block_homework_save_homeworktime with the user ID and data\n Ajax.call([{\n methodname: 'block_homework_save_homeworktime', // Your PHP function that will handle the data\n args: {\n user: userID,\n timeCompleted: timeData,\n },\n done: function() {\n // Close the modal after successful submission\n modal.destroy();\n location.reload();\n },\n fail: function(error) {\n console.error(\"Failed to save data:\", error);\n }\n }]);\n};\n"],"names":["_interopRequireDefault","e","__esModule","default","_jquery","_ajax","_modals","_exports","init","async","$","document","ready","on","Ajax","call","methodname","args","homeworkID","target","id","done","response","modal","MyModal","create","title","courseurl","course","homeworkurl","duedate","body","html","large","removeOnClose","show","getRoot","preventDefault","handleFormSubmit","userID","destroy","fail","error","Error","JSON","stringify","literatureInputFields","querySelectorAll","linksInputFields","videosInputFields","timeData","inputField","value","push","time","length","user","timeCompleted","location","reload","console"],"mappings":"qIAE4C,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;;kFAF5CG,QAAAJ,uBAAAI,SACAC,MAAAL,uBAAAK,OACAC,QAAAN,uBAAAM,SAsDEC,SAAAC,KArCkBC,gBAEhB,EAAAC,iBAAEC,UAAUC,OAAM,YACd,EAAAF,QAAAA,SAAE,eAAeG,GAAG,SAAUZ,IAC1Ba,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CACFC,WAAYjB,EAAEkB,OAAOC,IAEzBC,KAAMZ,eAAea,UACjB,MAAMC,YAAcC,QAAOrB,QAACsB,OAAO,CAE/BC,MAAO,YAAcJ,SAASK,UAAY,KAAOL,SAASM,OAAS,kBAAoBN,SAASO,YAAc,KAAOP,SAASI,MAAQ,UAAYJ,SAASQ,QAC3JC,KAAM,GAAGT,SAASU,OAClBC,OAAO,EACPC,eAAe,UAGbX,MAAMY,OAGZZ,MAAMa,UAAUvB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAEoC,iBACFC,iBAAiBC,OAAQhB,MAAM,IAGnCA,MAAMa,UAAUvB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAEoC,iBACFd,MAAMiB,SAAS,GAEtB,EACDC,KAAOC,QACH,MAAM,IAAIC,MAAM,yCAAyCC,KAAKC,UAAUH,SAAS,IAEtF,GAEX,GAAE,EAQN,MAAMJ,iBAAmBA,CAACC,OAAQhB,SAC9B,IAAIuB,sBAAwBnC,SAASoC,iBAAiB,6BAClDC,iBAAmBrC,SAASoC,iBAAiB,wBAC7CE,kBAAoBtC,SAASoC,iBAAiB,yBAC9CG,SAAW,GAEf,IAAK,IAAIC,cAAcL,sBACM,KAArBK,WAAWC,OACXF,SAASG,KAAK,CACVjC,GAAI+B,WAAW/B,GACfkC,KAAMH,WAAWC,QAI7B,IAAK,IAAID,cAAcH,iBACM,KAArBG,WAAWC,OACXF,SAASG,KAAK,CACVjC,GAAI+B,WAAW/B,GACfkC,KAAMH,WAAWC,QAI7B,IAAK,IAAID,cAAcF,kBACM,KAArBE,WAAWC,OACXF,SAASG,KAAK,CACVjC,GAAI+B,WAAW/B,GACfkC,KAAMH,WAAWC,QAMxBF,SAASK,OAMdzC,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,mCACZC,KAAM,CACFuC,KAAMjB,OACNkB,cAAeP,UAEnB7B,KAAM,WAEFE,MAAMiB,UACNkB,SAASC,QACZ,EACDlB,KAAM,SAASC,OACXkB,QAAQlB,MAAM,uBAAwBA,MAC1C,KAlBAnB,MAAMiB,SAmBP,CACL"} \ No newline at end of file diff --git a/server/moodle/blocks/homework/amd/build/clickStats.min.js b/server/moodle/blocks/homework/amd/build/clickStats.min.js new file mode 100644 index 00000000..49611158 --- /dev/null +++ b/server/moodle/blocks/homework/amd/build/clickStats.min.js @@ -0,0 +1,11 @@ +define("block_homework/clickStats",["exports","jquery","core/ajax","block_homework/modals"],(function(_exports,_jquery,_ajax,_modals){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}} +/** + * Homework/amd/src/clickStats.js + * + * @package + * @copyright 2024, cs-24-sw-5-01 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_ajax=_interopRequireDefault(_ajax),_modals=_interopRequireDefault(_modals);_exports.init=async userID=>{(0,_jquery.default)(document).ready((function(){(0,_jquery.default)(".stats-btn").on("click",(e=>{_ajax.default.call([{methodname:"block_homework_get_stats_modal",args:{},done:async function(response){const modal=await _modals.default.create({title:"Your homework stats",body:`${response.html}`,large:!0,removeOnClose:!0});await modal.show(),modal.getRoot().on("click",'[data-action="submit"]',(e=>{e.preventDefault(),modal.destroy()})),modal.getRoot().on("click",'[data-action="cancel"]',(e=>{e.preventDefault(),modal.destroy()}))},fail:error=>{throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`)}}])}))}))}})); + +//# sourceMappingURL=clickStats.min.js.map \ No newline at end of file diff --git a/server/moodle/blocks/homework/amd/build/clickStats.min.js.map b/server/moodle/blocks/homework/amd/build/clickStats.min.js.map new file mode 100644 index 00000000..364bea34 --- /dev/null +++ b/server/moodle/blocks/homework/amd/build/clickStats.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"clickStats.min.js","sources":["../src/clickStats.js"],"sourcesContent":["import $ from 'jquery';\nimport Ajax from 'core/ajax';\nimport MyModal from 'block_homework/modals';\n\n/**\n * Homework/amd/src/clickStats.js\n *\n * @package\n * @copyright 2024, cs-24-sw-5-01 \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n\n/**\n * Fetches and initializes the completion modal for the homework module that was clicked on.\n * @param userID ID of currently logged-in user.\n * @returns {Promise} A promise that, when fulfilled, opens the modal\n */\nexport const init = async(userID) => {\n // Create the modal using block_homework_get_stats_modal\n $(document).ready(function() {\n $('.stats-btn').on('click', (e) => {\n Ajax.call([{\n methodname: 'block_homework_get_stats_modal',\n args: {},\n done: async function(response) {\n const modal = await MyModal.create({\n // eslint-disable-next-line max-len\n title: \"Your homework stats\",\n body: `${response.html}`,\n large: true,\n removeOnClose: true,\n });\n // Show the modal.\n await modal.show();\n\n // Attach event listeners for buttons\n modal.getRoot().on('click', '[data-action=\"submit\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n\n modal.getRoot().on('click', '[data-action=\"cancel\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n },\n fail: (error) => {\n throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`);\n }\n }]);\n });\n });\n};"],"names":["_interopRequireDefault","e","__esModule","default","_jquery","_ajax","_modals","_exports","init","async","$","document","ready","on","Ajax","call","methodname","args","done","response","modal","MyModal","create","title","body","html","large","removeOnClose","show","getRoot","preventDefault","destroy","fail","error","Error","JSON","stringify"],"mappings":"sIAE4C,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;;kFAF5CG,QAAAJ,uBAAAI,SACAC,MAAAL,uBAAAK,OACAC,QAAAN,uBAAAM,SAoDEC,SAAAC,KAnCkBC,gBAEhB,EAAAC,iBAAEC,UAAUC,OAAM,YACd,EAAAF,QAAAA,SAAE,cAAcG,GAAG,SAAUZ,IACzBa,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,iCACZC,KAAM,CAAE,EACRC,KAAMT,eAAeU,UACjB,MAAMC,YAAcC,QAAOlB,QAACmB,OAAO,CAE/BC,MAAO,sBACPC,KAAM,GAAGL,SAASM,OAClBC,OAAO,EACPC,eAAe,UAGbP,MAAMQ,OAGZR,MAAMS,UAAUhB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAE6B,iBACFV,MAAMW,SAAS,IAGnBX,MAAMS,UAAUhB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAE6B,iBACFV,MAAMW,SAAS,GAEtB,EACDC,KAAOC,QACH,MAAM,IAAIC,MAAM,yCAAyCC,KAAKC,UAAUH,SAAS,IAEtF,GAEX,GAAE,CACJ"} \ No newline at end of file diff --git a/server/moodle/blocks/homework/amd/src/clickInfo.js b/server/moodle/blocks/homework/amd/src/clickInfo.js index 45aed4b6..a5fb2387 100644 --- a/server/moodle/blocks/homework/amd/src/clickInfo.js +++ b/server/moodle/blocks/homework/amd/src/clickInfo.js @@ -65,13 +65,11 @@ const handleFormSubmit = (userID, modal) => { let literatureInputFields = document.querySelectorAll('.homework-time-literature'); let linksInputFields = document.querySelectorAll('.homework-time-links'); let videosInputFields = document.querySelectorAll('.homework-time-videos'); - let timeData1 = []; - let timeData2 = []; - let timeData3 = []; + let timeData = [] // Finds the data of all input fields, both literature, link and video, and adds the ID and time to an array. for (let inputField of literatureInputFields) { if (inputField.value !== "") { - timeData1.push({ + timeData.push({ id: inputField.id, time: inputField.value, }); @@ -79,7 +77,7 @@ const handleFormSubmit = (userID, modal) => { } for (let inputField of linksInputFields) { if (inputField.value !== "") { - timeData2.push({ + timeData.push({ id: inputField.id, time: inputField.value, }); @@ -87,7 +85,7 @@ const handleFormSubmit = (userID, modal) => { } for (let inputField of videosInputFields) { if (inputField.value !== "") { - timeData3.push({ + timeData.push({ id: inputField.id, time: inputField.value, }); @@ -95,7 +93,7 @@ const handleFormSubmit = (userID, modal) => { } // If no data has been filled, do nothing. - if (!timeData1.length && !timeData2.length && !timeData3.length) { + if (!timeData.length) { modal.destroy(); return; } @@ -105,9 +103,7 @@ const handleFormSubmit = (userID, modal) => { methodname: 'block_homework_save_homeworktime', // Your PHP function that will handle the data args: { user: userID, - timeCompletedLiterature: timeData1, - timeCompletedLinks: timeData2, - timeCompletedVideos: timeData3, + timeCompleted: timeData, }, done: function() { // Close the modal after successful submission diff --git a/server/moodle/blocks/homework/amd/src/clickStats.js b/server/moodle/blocks/homework/amd/src/clickStats.js new file mode 100644 index 00000000..d5e7646b --- /dev/null +++ b/server/moodle/blocks/homework/amd/src/clickStats.js @@ -0,0 +1,55 @@ +import $ from 'jquery'; +import Ajax from 'core/ajax'; +import MyModal from 'block_homework/modals'; + +/** + * Homework/amd/src/clickStats.js + * + * @package + * @copyright 2024, cs-24-sw-5-01 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + */ + + +/** + * Fetches and initializes the completion modal for the homework module that was clicked on. + * @param userID ID of currently logged-in user. + * @returns {Promise} A promise that, when fulfilled, opens the modal + */ +export const init = async(userID) => { + // Create the modal using block_homework_get_stats_modal + $(document).ready(function() { + $('.stats-btn').on('click', (e) => { + Ajax.call([{ + methodname: 'block_homework_get_stats_modal', + args: {}, + done: async function(response) { + const modal = await MyModal.create({ + // eslint-disable-next-line max-len + title: "Your homework stats", + body: `${response.html}`, + large: true, + removeOnClose: true, + }); + // Show the modal. + await modal.show(); + + // Attach event listeners for buttons + modal.getRoot().on('click', '[data-action="submit"]', (e) => { + e.preventDefault(); + modal.destroy(); + }); + + modal.getRoot().on('click', '[data-action="cancel"]', (e) => { + e.preventDefault(); + modal.destroy(); + }); + }, + fail: (error) => { + throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`); + } + }]); + }); + }); +}; \ No newline at end of file diff --git a/server/moodle/blocks/homework/block_homework.php b/server/moodle/blocks/homework/block_homework.php index d2f19f62..0b6dd9c5 100644 --- a/server/moodle/blocks/homework/block_homework.php +++ b/server/moodle/blocks/homework/block_homework.php @@ -142,6 +142,7 @@ public function get_content() { $this->page->requires->js_call_amd('block_homework/map_link_injector', 'init'); $this->page->requires->js_call_amd('block_homework/filter', 'init'); $this->page->requires->js_call_amd('block_homework/clickInfo', 'init', [$USER->id]); + $this->page->requires->js_call_amd('block_homework/clickStats', 'init'); return $this->content; } diff --git a/server/moodle/blocks/homework/classes/external/get_stats_modal.php b/server/moodle/blocks/homework/classes/external/get_stats_modal.php new file mode 100644 index 00000000..d3d58a38 --- /dev/null +++ b/server/moodle/blocks/homework/classes/external/get_stats_modal.php @@ -0,0 +1,135 @@ +. + +namespace block_homework\external; + +defined('MOODLE_INTERNAL') || die(); +global $CFG; + +use coding_exception; +use core_external\external_api; +use dml_exception; +use core_external\external_function_parameters; +use core_external\external_value; +use core_external\external_single_structure; +use JsonException; +use Mustache_Engine; + +/** + * The external function for requesting the modal for plugin. + * @copyright group 1 + * @package block_homework + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class get_stats_modal extends external_api { + /** + * Returns the parameters for the execute function. + * @return external_function_parameters + */ + public static function execute_parameters(): external_function_parameters { + return new external_function_parameters([]); + } + + /** + * Generates the custom HTML for the homework chooser modal. + * + * @param int $homeworkID The ID of the homework item + * @return string[] - The HTML to be shown client-side + * @throws dml_exception|JsonException + */ + public static function execute(): array { + global $DB, $USER; + + // The weight indicates the number of minutes after which the user's reading speed will be prioritized over the average. + $weight = 180; + // The global reading speed in minutes. + $globalreadingspeed = 0.5; + + $sql = " + SELECT c.*, hm.startpage, hm.endpage + FROM {completions} c + LEFT JOIN {homework_materials} hm ON c.material_id = hm.id + WHERE c.usermodified = :userid + "; + $params = ['userid' => $USER->id]; + $records = $DB->get_records_sql($sql, $params); + + $availablematerials = $DB->get_records('homework_materials'); + + $totalminutes = 0; + $totalreadingtime = 0; + $totalpages = 0; + $totaldays = 0; + + foreach ($records as $record) { + + // Timestamps are in seconds, so we get the day difference by dividing by seconds per day. + // Use the time from the first homework completion as the start time for these stats. + $totaldays = floor(time() - ($record->timecreated) / 86400); + + $totalminutes += $record->timetaken; + + $startpage = $record->startpage; + $endpage = $record->endpage; + + if ($startpage != null && $endpage != null) { + $totalpages += $endpage - $startpage; + $totalreadingtime += $record->timetaken; + } + } + $weightedreadingspeed = $globalreadingspeed; + $timeperday = 0; + if ($totaldays != 0) { + $timeperday = $totalminutes / $totaldays; + } + + if ($totalpages != 0) { + $readingspeed = $totalreadingtime / $totalpages; + // The reading speed is weighted. When no pages have been read, it will be the global average a page per minute. + // Once the number of minutes reaches the weight, the user's speed will be weighted more than the average. + $weightedreadingspeed = $globalreadingspeed + ($readingspeed - $globalreadingspeed) * $totalminutes / ($totalminutes + $weight); + } + + $percentcompleted = 0; + if (count($records) && count($availablematerials)) { + $percentcompleted = count($records) / count($availablematerials) * 100; + } + + $mustache = new Mustache_Engine(); + + // Prepare data for the template. + $content = [ + 'weightedreadingspeed' => strip_tags($weightedreadingspeed), + 'percentcompleted' => strip_tags($percentcompleted), + 'timeperday' => strip_tags($timeperday), + + ]; + + $html = $mustache->render(file_get_contents(__DIR__ . "/../../templates/stats.mustache"), $content); + + return ['html' => $html]; + } + + /** + * Returns the structure of the function's response. + * @return external_single_structure - Definition of the function's return type and description + */ + public static function execute_returns(): external_single_structure { + return new external_single_structure([ + 'html' => new external_value(PARAM_TEXT, 'modal thml'), + ]); + } +} diff --git a/server/moodle/blocks/homework/db/services.php b/server/moodle/blocks/homework/db/services.php index 3b9406bc..71d83809 100644 --- a/server/moodle/blocks/homework/db/services.php +++ b/server/moodle/blocks/homework/db/services.php @@ -28,12 +28,20 @@ $functions = [ 'block_homework_get_infohomework_modal' => [ - 'classname' => 'block_homework\external\get_infohomework_modal', - 'methodname' => 'execute', - 'classpath' => 'blocks/homework/classes/external/get_infohomework_modal.php', - 'description' => 'Get the homework info content', - 'type' => 'read', - 'ajax' => true, + 'classname' => 'block_homework\external\get_infohomework_modal', + 'methodname' => 'execute', + 'classpath' => 'blocks/homework/classes/external/get_infohomework_modal.php', + 'description' => 'Get the homework info content', + 'type' => 'read', + 'ajax' => true, + ], + 'block_homework_get_stats_modal' => [ + 'classname' => 'block_homework\external\get_stats_modal', + 'methodname' => 'execute', + 'classpath' => 'blocks/homework/classes/external/get_stats_modal.php', + 'description' => 'Get the homework stats content', + 'type' => 'read', + 'ajax' => true, ], 'block_homework_save_homeworktime' => [ 'classname' => 'block_homework\external\save_homeworktime', diff --git a/server/moodle/blocks/homework/templates/data.mustache b/server/moodle/blocks/homework/templates/data.mustache index 878d82ae..f6b94137 100644 --- a/server/moodle/blocks/homework/templates/data.mustache +++ b/server/moodle/blocks/homework/templates/data.mustache @@ -35,7 +35,7 @@ - +
diff --git a/server/moodle/blocks/homework/templates/stats.mustache b/server/moodle/blocks/homework/templates/stats.mustache new file mode 100644 index 00000000..4a946a44 --- /dev/null +++ b/server/moodle/blocks/homework/templates/stats.mustache @@ -0,0 +1,9 @@ +{{< core/modal }} +
+
+
Average reading speed: {{$weightedreadingspeed}} words per minutes.
+
Average homework time per day: {{$timeperday}} minutes.
+
Percentage of homework completed: {{$percentcompleted}}%
+
+
+{{/ core/modal }} diff --git a/server/moodle/blocks/homework/version.php b/server/moodle/blocks/homework/version.php index 40d98db0..eb6be4bd 100644 --- a/server/moodle/blocks/homework/version.php +++ b/server/moodle/blocks/homework/version.php @@ -27,5 +27,5 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'block_homework'; // Plugin name. -$plugin->version = 2024101401; // Plugin version. +$plugin->version = 2024101402; // Plugin version. $plugin->requires = 2016052300; // Moodle version. From ed3ddf6540adc16fb789a5135a2dcac77ebe1f72 Mon Sep 17 00:00:00 2001 From: Allan Vester Date: Mon, 25 Nov 2024 19:00:13 +0100 Subject: [PATCH 2/6] Modal now working --- .../classes/external/get_stats_modal.php | 43 ++++++++++++------- .../blocks/homework/templates/stats.mustache | 14 +++--- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/server/moodle/blocks/homework/classes/external/get_stats_modal.php b/server/moodle/blocks/homework/classes/external/get_stats_modal.php index d3d58a38..b1d3f4cb 100644 --- a/server/moodle/blocks/homework/classes/external/get_stats_modal.php +++ b/server/moodle/blocks/homework/classes/external/get_stats_modal.php @@ -56,16 +56,16 @@ public static function execute(): array { // The weight indicates the number of minutes after which the user's reading speed will be prioritized over the average. $weight = 180; // The global reading speed in minutes. - $globalreadingspeed = 0.5; + $globalreadingspeed = 2; - $sql = " + $records = $DB->get_records_sql( + " SELECT c.*, hm.startpage, hm.endpage FROM {completions} c LEFT JOIN {homework_materials} hm ON c.material_id = hm.id - WHERE c.usermodified = :userid - "; - $params = ['userid' => $USER->id]; - $records = $DB->get_records_sql($sql, $params); + WHERE c.usermodified = :userid", + ['userid' => $USER->id] + ); $availablematerials = $DB->get_records('homework_materials'); @@ -75,10 +75,9 @@ public static function execute(): array { $totaldays = 0; foreach ($records as $record) { - // Timestamps are in seconds, so we get the day difference by dividing by seconds per day. // Use the time from the first homework completion as the start time for these stats. - $totaldays = floor(time() - ($record->timecreated) / 86400); + $totaldays = floor((time() - $record->timecreated) / 86400) + 1; $totalminutes += $record->timetaken; @@ -100,7 +99,8 @@ public static function execute(): array { $readingspeed = $totalreadingtime / $totalpages; // The reading speed is weighted. When no pages have been read, it will be the global average a page per minute. // Once the number of minutes reaches the weight, the user's speed will be weighted more than the average. - $weightedreadingspeed = $globalreadingspeed + ($readingspeed - $globalreadingspeed) * $totalminutes / ($totalminutes + $weight); + $weightedreadingspeed = $globalreadingspeed + ($readingspeed - $globalreadingspeed) * + $totalminutes / ($totalminutes + $weight); } $percentcompleted = 0; @@ -112,15 +112,26 @@ public static function execute(): array { // Prepare data for the template. $content = [ - 'weightedreadingspeed' => strip_tags($weightedreadingspeed), - 'percentcompleted' => strip_tags($percentcompleted), - 'timeperday' => strip_tags($timeperday), - + 'weightedreadingspeed' => round($weightedreadingspeed, 2), + 'percentcompleted' => round($percentcompleted, 2), + 'timeperday' => round($timeperday, 2), ]; - $html = $mustache->render(file_get_contents(__DIR__ . "/../../templates/stats.mustache"), $content); + $templatepath = __DIR__ . "/../../templates/stats.mustache"; + if (!file_exists($templatepath)) { + throw new coding_exception("Template file does not exist: " . $templatepath); + } - return ['html' => $html]; + $templatecontent = file_get_contents($templatepath); + if (!$templatecontent) { + throw new coding_exception("Template file is empty or could not be read: " . $templatepath); + } + + $html = $mustache->render($templatecontent, $content); + + return [ + 'html' => $html, + ]; } /** @@ -129,7 +140,7 @@ public static function execute(): array { */ public static function execute_returns(): external_single_structure { return new external_single_structure([ - 'html' => new external_value(PARAM_TEXT, 'modal thml'), + 'html' => new external_value(PARAM_RAW, 'HTML for the stats modal'), ]); } } diff --git a/server/moodle/blocks/homework/templates/stats.mustache b/server/moodle/blocks/homework/templates/stats.mustache index 4a946a44..bc7841b3 100644 --- a/server/moodle/blocks/homework/templates/stats.mustache +++ b/server/moodle/blocks/homework/templates/stats.mustache @@ -1,9 +1,7 @@ -{{< core/modal }} -
-
-
Average reading speed: {{$weightedreadingspeed}} words per minutes.
-
Average homework time per day: {{$timeperday}} minutes.
-
Percentage of homework completed: {{$percentcompleted}}%
-
+
+
+
Average reading speed: {{weightedreadingspeed}} minutes per page.
+
Average homework time per day: {{timeperday}} minutes.
+
Percentage of homework completed: {{percentcompleted}}%.
-{{/ core/modal }} +
From 50a766ea2092210a629e8e7777b2b089bb9f20de Mon Sep 17 00:00:00 2001 From: AllanVester Date: Tue, 26 Nov 2024 12:57:28 +0100 Subject: [PATCH 3/6] Fully working --- .../homework/amd/build/clickInfo.min.js | 2 +- .../homework/amd/build/clickInfo.min.js.map | 2 +- .../homework/amd/build/clickStats.min.js | 2 +- .../homework/amd/build/clickStats.min.js.map | 2 +- .../blocks/homework/amd/src/clickInfo.js | 3 +- .../blocks/homework/amd/src/clickStats.js | 8 +- .../moodle/blocks/homework/block_homework.php | 98 ++++++++++++++++++- .../external/get_infohomework_modal.php | 7 +- .../classes/external/get_stats_modal.php | 77 +++------------ .../blocks/homework/templates/data.mustache | 1 + .../templates/timeinfotemplate.mustache | 3 + 11 files changed, 129 insertions(+), 76 deletions(-) diff --git a/server/moodle/blocks/homework/amd/build/clickInfo.min.js b/server/moodle/blocks/homework/amd/build/clickInfo.min.js index 94e0b72d..b9ab28a9 100644 --- a/server/moodle/blocks/homework/amd/build/clickInfo.min.js +++ b/server/moodle/blocks/homework/amd/build/clickInfo.min.js @@ -6,6 +6,6 @@ define("block_homework/clickInfo",["exports","jquery","core/ajax","block_homewor * @copyright 2024, cs-24-sw-5-01 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_ajax=_interopRequireDefault(_ajax),_modals=_interopRequireDefault(_modals);_exports.init=async userID=>{(0,_jquery.default)(document).ready((function(){(0,_jquery.default)(".timebutton").on("click",(e=>{_ajax.default.call([{methodname:"block_homework_get_infohomework_modal",args:{homeworkID:e.target.id},done:async function(response){const modal=await _modals.default.create({title:""+response.course+": "+response.title+" | "+response.duedate,body:`${response.html}`,large:!0,removeOnClose:!0});await modal.show(),modal.getRoot().on("click",'[data-action="submit"]',(e=>{e.preventDefault(),handleFormSubmit(userID,modal)})),modal.getRoot().on("click",'[data-action="cancel"]',(e=>{e.preventDefault(),modal.destroy()}))},fail:error=>{throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`)}}])}))}))};const handleFormSubmit=(userID,modal)=>{let literatureInputFields=document.querySelectorAll(".homework-time-literature"),linksInputFields=document.querySelectorAll(".homework-time-links"),videosInputFields=document.querySelectorAll(".homework-time-videos"),timeData=[];for(let inputField of literatureInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});for(let inputField of linksInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});for(let inputField of videosInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});timeData.length?_ajax.default.call([{methodname:"block_homework_save_homeworktime",args:{user:userID,timeCompleted:timeData},done:function(){modal.destroy(),location.reload()},fail:function(error){console.error("Failed to save data:",error)}}]):modal.destroy()}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_ajax=_interopRequireDefault(_ajax),_modals=_interopRequireDefault(_modals);_exports.init=async(userID,readingspeed)=>{(0,_jquery.default)(document).ready((function(){(0,_jquery.default)(".timebutton").on("click",(e=>{_ajax.default.call([{methodname:"block_homework_get_infohomework_modal",args:{homeworkID:e.target.id,readingspeed:readingspeed},done:async function(response){const modal=await _modals.default.create({title:""+response.course+": "+response.title+" | "+response.duedate,body:`${response.html}`,large:!0,removeOnClose:!0});await modal.show(),modal.getRoot().on("click",'[data-action="submit"]',(e=>{e.preventDefault(),handleFormSubmit(userID,modal)})),modal.getRoot().on("click",'[data-action="cancel"]',(e=>{e.preventDefault(),modal.destroy()}))},fail:error=>{throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`)}}])}))}))};const handleFormSubmit=(userID,modal)=>{let literatureInputFields=document.querySelectorAll(".homework-time-literature"),linksInputFields=document.querySelectorAll(".homework-time-links"),videosInputFields=document.querySelectorAll(".homework-time-videos"),timeData=[];for(let inputField of literatureInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});for(let inputField of linksInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});for(let inputField of videosInputFields)""!==inputField.value&&timeData.push({id:inputField.id,time:inputField.value});timeData.length?_ajax.default.call([{methodname:"block_homework_save_homeworktime",args:{user:userID,timeCompleted:timeData},done:function(){modal.destroy(),location.reload()},fail:function(error){console.error("Failed to save data:",error)}}]):modal.destroy()}})); //# sourceMappingURL=clickInfo.min.js.map \ No newline at end of file diff --git a/server/moodle/blocks/homework/amd/build/clickInfo.min.js.map b/server/moodle/blocks/homework/amd/build/clickInfo.min.js.map index c5cee162..f030745c 100644 --- a/server/moodle/blocks/homework/amd/build/clickInfo.min.js.map +++ b/server/moodle/blocks/homework/amd/build/clickInfo.min.js.map @@ -1 +1 @@ -{"version":3,"file":"clickInfo.min.js","sources":["../src/clickInfo.js"],"sourcesContent":["import $ from 'jquery';\nimport Ajax from 'core/ajax';\nimport MyModal from 'block_homework/modals';\n\n/**\n * Homework/amd/src/modal_homework.js\n *\n * @package\n * @copyright 2024, cs-24-sw-5-01 \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n\n/**\n * Fetches and initializes the completion modal for the homework module that was clicked on.\n * @param userID ID of currently logged-in user.\n * @returns {Promise} A promise that, when fulfilled, opens the modal\n */\nexport const init = async(userID) => {\n // Create the modal using block_homework_get_infohomework_modal\n $(document).ready(function() {\n $('.timebutton').on('click', (e) => {\n Ajax.call([{\n methodname: 'block_homework_get_infohomework_modal',\n args: {\n homeworkID: e.target.id,\n },\n done: async function(response) {\n const modal = await MyModal.create({\n // eslint-disable-next-line max-len\n title: \"\" + response.course + \": \" + response.title + \" | \" + response.duedate,\n body: `${response.html}`,\n large: true,\n removeOnClose: true,\n });\n // Show the modal.\n await modal.show();\n\n // Attach event listeners for buttons\n modal.getRoot().on('click', '[data-action=\"submit\"]', (e) => {\n e.preventDefault();\n handleFormSubmit(userID, modal);\n });\n\n modal.getRoot().on('click', '[data-action=\"cancel\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n },\n fail: (error) => {\n throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`);\n }\n }]);\n });\n });\n};\n\n/**\n * Handle clicking the submit button of the form and updating the database with completion and times\n * @param userID ID of currently logged-in user\n * @param modal The modal that is being submitted\n */\nconst handleFormSubmit = (userID, modal) => {\n let literatureInputFields = document.querySelectorAll('.homework-time-literature');\n let linksInputFields = document.querySelectorAll('.homework-time-links');\n let videosInputFields = document.querySelectorAll('.homework-time-videos');\n let timeData = []\n // Finds the data of all input fields, both literature, link and video, and adds the ID and time to an array.\n for (let inputField of literatureInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n for (let inputField of linksInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n for (let inputField of videosInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n\n // If no data has been filled, do nothing.\n if (!timeData.length) {\n modal.destroy();\n return;\n }\n\n // If data has been filled, call block_homework_save_homeworktime with the user ID and data\n Ajax.call([{\n methodname: 'block_homework_save_homeworktime', // Your PHP function that will handle the data\n args: {\n user: userID,\n timeCompleted: timeData,\n },\n done: function() {\n // Close the modal after successful submission\n modal.destroy();\n location.reload();\n },\n fail: function(error) {\n console.error(\"Failed to save data:\", error);\n }\n }]);\n};\n"],"names":["_interopRequireDefault","e","__esModule","default","_jquery","_ajax","_modals","_exports","init","async","$","document","ready","on","Ajax","call","methodname","args","homeworkID","target","id","done","response","modal","MyModal","create","title","courseurl","course","homeworkurl","duedate","body","html","large","removeOnClose","show","getRoot","preventDefault","handleFormSubmit","userID","destroy","fail","error","Error","JSON","stringify","literatureInputFields","querySelectorAll","linksInputFields","videosInputFields","timeData","inputField","value","push","time","length","user","timeCompleted","location","reload","console"],"mappings":"qIAE4C,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;;kFAF5CG,QAAAJ,uBAAAI,SACAC,MAAAL,uBAAAK,OACAC,QAAAN,uBAAAM,SAsDEC,SAAAC,KArCkBC,gBAEhB,EAAAC,iBAAEC,UAAUC,OAAM,YACd,EAAAF,QAAAA,SAAE,eAAeG,GAAG,SAAUZ,IAC1Ba,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CACFC,WAAYjB,EAAEkB,OAAOC,IAEzBC,KAAMZ,eAAea,UACjB,MAAMC,YAAcC,QAAOrB,QAACsB,OAAO,CAE/BC,MAAO,YAAcJ,SAASK,UAAY,KAAOL,SAASM,OAAS,kBAAoBN,SAASO,YAAc,KAAOP,SAASI,MAAQ,UAAYJ,SAASQ,QAC3JC,KAAM,GAAGT,SAASU,OAClBC,OAAO,EACPC,eAAe,UAGbX,MAAMY,OAGZZ,MAAMa,UAAUvB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAEoC,iBACFC,iBAAiBC,OAAQhB,MAAM,IAGnCA,MAAMa,UAAUvB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAEoC,iBACFd,MAAMiB,SAAS,GAEtB,EACDC,KAAOC,QACH,MAAM,IAAIC,MAAM,yCAAyCC,KAAKC,UAAUH,SAAS,IAEtF,GAEX,GAAE,EAQN,MAAMJ,iBAAmBA,CAACC,OAAQhB,SAC9B,IAAIuB,sBAAwBnC,SAASoC,iBAAiB,6BAClDC,iBAAmBrC,SAASoC,iBAAiB,wBAC7CE,kBAAoBtC,SAASoC,iBAAiB,yBAC9CG,SAAW,GAEf,IAAK,IAAIC,cAAcL,sBACM,KAArBK,WAAWC,OACXF,SAASG,KAAK,CACVjC,GAAI+B,WAAW/B,GACfkC,KAAMH,WAAWC,QAI7B,IAAK,IAAID,cAAcH,iBACM,KAArBG,WAAWC,OACXF,SAASG,KAAK,CACVjC,GAAI+B,WAAW/B,GACfkC,KAAMH,WAAWC,QAI7B,IAAK,IAAID,cAAcF,kBACM,KAArBE,WAAWC,OACXF,SAASG,KAAK,CACVjC,GAAI+B,WAAW/B,GACfkC,KAAMH,WAAWC,QAMxBF,SAASK,OAMdzC,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,mCACZC,KAAM,CACFuC,KAAMjB,OACNkB,cAAeP,UAEnB7B,KAAM,WAEFE,MAAMiB,UACNkB,SAASC,QACZ,EACDlB,KAAM,SAASC,OACXkB,QAAQlB,MAAM,uBAAwBA,MAC1C,KAlBAnB,MAAMiB,SAmBP,CACL"} \ No newline at end of file +{"version":3,"file":"clickInfo.min.js","sources":["../src/clickInfo.js"],"sourcesContent":["import $ from 'jquery';\nimport Ajax from 'core/ajax';\nimport MyModal from 'block_homework/modals';\n\n/**\n * Homework/amd/src/modal_homework.js\n *\n * @package\n * @copyright 2024, cs-24-sw-5-01 \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n\n/**\n * Fetches and initializes the completion modal for the homework module that was clicked on.\n * @param userID ID of currently logged-in user.\n * @returns {Promise} A promise that, when fulfilled, opens the modal\n */\nexport const init = async(userID, readingspeed) => {\n // Create the modal using block_homework_get_infohomework_modal\n $(document).ready(function() {\n $('.timebutton').on('click', (e) => {\n Ajax.call([{\n methodname: 'block_homework_get_infohomework_modal',\n args: {\n homeworkID: e.target.id,\n readingspeed: readingspeed\n },\n done: async function(response) {\n const modal = await MyModal.create({\n // eslint-disable-next-line max-len\n title: \"\" + response.course + \": \" + response.title + \" | \" + response.duedate,\n body: `${response.html}`,\n large: true,\n removeOnClose: true,\n });\n // Show the modal.\n await modal.show();\n\n // Attach event listeners for buttons\n modal.getRoot().on('click', '[data-action=\"submit\"]', (e) => {\n e.preventDefault();\n handleFormSubmit(userID, modal);\n });\n\n modal.getRoot().on('click', '[data-action=\"cancel\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n },\n fail: (error) => {\n throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`);\n }\n }]);\n });\n });\n};\n\n/**\n * Handle clicking the submit button of the form and updating the database with completion and times\n * @param userID ID of currently logged-in user\n * @param modal The modal that is being submitted\n */\nconst handleFormSubmit = (userID, modal) => {\n let literatureInputFields = document.querySelectorAll('.homework-time-literature');\n let linksInputFields = document.querySelectorAll('.homework-time-links');\n let videosInputFields = document.querySelectorAll('.homework-time-videos');\n let timeData = []\n // Finds the data of all input fields, both literature, link and video, and adds the ID and time to an array.\n for (let inputField of literatureInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n for (let inputField of linksInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n for (let inputField of videosInputFields) {\n if (inputField.value !== \"\") {\n timeData.push({\n id: inputField.id,\n time: inputField.value,\n });\n }\n }\n\n // If no data has been filled, do nothing.\n if (!timeData.length) {\n modal.destroy();\n return;\n }\n\n // If data has been filled, call block_homework_save_homeworktime with the user ID and data\n Ajax.call([{\n methodname: 'block_homework_save_homeworktime', // Your PHP function that will handle the data\n args: {\n user: userID,\n timeCompleted: timeData,\n },\n done: function() {\n // Close the modal after successful submission\n modal.destroy();\n location.reload();\n },\n fail: function(error) {\n console.error(\"Failed to save data:\", error);\n }\n }]);\n};\n"],"names":["_interopRequireDefault","e","__esModule","default","_jquery","_ajax","_modals","_exports","init","async","userID","readingspeed","$","document","ready","on","Ajax","call","methodname","args","homeworkID","target","id","done","response","modal","MyModal","create","title","courseurl","course","homeworkurl","duedate","body","html","large","removeOnClose","show","getRoot","preventDefault","handleFormSubmit","destroy","fail","error","Error","JSON","stringify","literatureInputFields","querySelectorAll","linksInputFields","videosInputFields","timeData","inputField","value","push","time","length","user","timeCompleted","location","reload","console"],"mappings":"qIAE4C,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;;kFAF5CG,QAAAJ,uBAAAI,SACAC,MAAAL,uBAAAK,OACAC,QAAAN,uBAAAM,SAuDEC,SAAAC,KAtCkBC,MAAMC,OAAQC,iBAE9B,EAAAC,iBAAEC,UAAUC,OAAM,YACd,EAAAF,QAAAA,SAAE,eAAeG,GAAG,SAAUd,IAC1Be,MAAIb,QAACc,KAAK,CAAC,CACPC,WAAY,wCACZC,KAAM,CACFC,WAAYnB,EAAEoB,OAAOC,GACrBX,aAAcA,cAElBY,KAAMd,eAAee,UACjB,MAAMC,YAAcC,QAAOvB,QAACwB,OAAO,CAE/BC,MAAO,YAAcJ,SAASK,UAAY,KAAOL,SAASM,OAAS,kBAAoBN,SAASO,YAAc,KAAOP,SAASI,MAAQ,UAAYJ,SAASQ,QAC3JC,KAAM,GAAGT,SAASU,OAClBC,OAAO,EACPC,eAAe,UAGbX,MAAMY,OAGZZ,MAAMa,UAAUvB,GAAG,QAAS,0BAA2Bd,IACnDA,EAAEsC,iBACFC,iBAAiB9B,OAAQe,MAAM,IAGnCA,MAAMa,UAAUvB,GAAG,QAAS,0BAA2Bd,IACnDA,EAAEsC,iBACFd,MAAMgB,SAAS,GAEtB,EACDC,KAAOC,QACH,MAAM,IAAIC,MAAM,yCAAyCC,KAAKC,UAAUH,SAAS,IAEtF,GAEX,GAAE,EAQN,MAAMH,iBAAmBA,CAAC9B,OAAQe,SAC9B,IAAIsB,sBAAwBlC,SAASmC,iBAAiB,6BAClDC,iBAAmBpC,SAASmC,iBAAiB,wBAC7CE,kBAAoBrC,SAASmC,iBAAiB,yBAC9CG,SAAW,GAEf,IAAK,IAAIC,cAAcL,sBACM,KAArBK,WAAWC,OACXF,SAASG,KAAK,CACVhC,GAAI8B,WAAW9B,GACfiC,KAAMH,WAAWC,QAI7B,IAAK,IAAID,cAAcH,iBACM,KAArBG,WAAWC,OACXF,SAASG,KAAK,CACVhC,GAAI8B,WAAW9B,GACfiC,KAAMH,WAAWC,QAI7B,IAAK,IAAID,cAAcF,kBACM,KAArBE,WAAWC,OACXF,SAASG,KAAK,CACVhC,GAAI8B,WAAW9B,GACfiC,KAAMH,WAAWC,QAMxBF,SAASK,OAMdxC,MAAIb,QAACc,KAAK,CAAC,CACPC,WAAY,mCACZC,KAAM,CACFsC,KAAM/C,OACNgD,cAAeP,UAEnB5B,KAAM,WAEFE,MAAMgB,UACNkB,SAASC,QACZ,EACDlB,KAAM,SAASC,OACXkB,QAAQlB,MAAM,uBAAwBA,MAC1C,KAlBAlB,MAAMgB,SAmBP,CACL"} \ No newline at end of file diff --git a/server/moodle/blocks/homework/amd/build/clickStats.min.js b/server/moodle/blocks/homework/amd/build/clickStats.min.js index 49611158..d3b03a80 100644 --- a/server/moodle/blocks/homework/amd/build/clickStats.min.js +++ b/server/moodle/blocks/homework/amd/build/clickStats.min.js @@ -6,6 +6,6 @@ define("block_homework/clickStats",["exports","jquery","core/ajax","block_homewo * @copyright 2024, cs-24-sw-5-01 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * - */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_ajax=_interopRequireDefault(_ajax),_modals=_interopRequireDefault(_modals);_exports.init=async userID=>{(0,_jquery.default)(document).ready((function(){(0,_jquery.default)(".stats-btn").on("click",(e=>{_ajax.default.call([{methodname:"block_homework_get_stats_modal",args:{},done:async function(response){const modal=await _modals.default.create({title:"Your homework stats",body:`${response.html}`,large:!0,removeOnClose:!0});await modal.show(),modal.getRoot().on("click",'[data-action="submit"]',(e=>{e.preventDefault(),modal.destroy()})),modal.getRoot().on("click",'[data-action="cancel"]',(e=>{e.preventDefault(),modal.destroy()}))},fail:error=>{throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`)}}])}))}))}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=_interopRequireDefault(_jquery),_ajax=_interopRequireDefault(_ajax),_modals=_interopRequireDefault(_modals);_exports.init=async stats=>{(0,_jquery.default)(document).ready((function(){(0,_jquery.default)(".stats-btn").on("click",(()=>{_ajax.default.call([{methodname:"block_homework_get_stats_modal",args:{stats:stats},done:async function(response){const modal=await _modals.default.create({title:"Your homework stats",body:`${response.html}`,large:!0,removeOnClose:!0});await modal.show(),modal.getRoot().on("click",'[data-action="submit"]',(e=>{e.preventDefault(),modal.destroy()})),modal.getRoot().on("click",'[data-action="cancel"]',(e=>{e.preventDefault(),modal.destroy()}))},fail:error=>{throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`)}}])}))}))}})); //# sourceMappingURL=clickStats.min.js.map \ No newline at end of file diff --git a/server/moodle/blocks/homework/amd/build/clickStats.min.js.map b/server/moodle/blocks/homework/amd/build/clickStats.min.js.map index 364bea34..3c8b56af 100644 --- a/server/moodle/blocks/homework/amd/build/clickStats.min.js.map +++ b/server/moodle/blocks/homework/amd/build/clickStats.min.js.map @@ -1 +1 @@ -{"version":3,"file":"clickStats.min.js","sources":["../src/clickStats.js"],"sourcesContent":["import $ from 'jquery';\nimport Ajax from 'core/ajax';\nimport MyModal from 'block_homework/modals';\n\n/**\n * Homework/amd/src/clickStats.js\n *\n * @package\n * @copyright 2024, cs-24-sw-5-01 \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n\n/**\n * Fetches and initializes the completion modal for the homework module that was clicked on.\n * @param userID ID of currently logged-in user.\n * @returns {Promise} A promise that, when fulfilled, opens the modal\n */\nexport const init = async(userID) => {\n // Create the modal using block_homework_get_stats_modal\n $(document).ready(function() {\n $('.stats-btn').on('click', (e) => {\n Ajax.call([{\n methodname: 'block_homework_get_stats_modal',\n args: {},\n done: async function(response) {\n const modal = await MyModal.create({\n // eslint-disable-next-line max-len\n title: \"Your homework stats\",\n body: `${response.html}`,\n large: true,\n removeOnClose: true,\n });\n // Show the modal.\n await modal.show();\n\n // Attach event listeners for buttons\n modal.getRoot().on('click', '[data-action=\"submit\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n\n modal.getRoot().on('click', '[data-action=\"cancel\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n },\n fail: (error) => {\n throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`);\n }\n }]);\n });\n });\n};"],"names":["_interopRequireDefault","e","__esModule","default","_jquery","_ajax","_modals","_exports","init","async","$","document","ready","on","Ajax","call","methodname","args","done","response","modal","MyModal","create","title","body","html","large","removeOnClose","show","getRoot","preventDefault","destroy","fail","error","Error","JSON","stringify"],"mappings":"sIAE4C,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;;kFAF5CG,QAAAJ,uBAAAI,SACAC,MAAAL,uBAAAK,OACAC,QAAAN,uBAAAM,SAoDEC,SAAAC,KAnCkBC,gBAEhB,EAAAC,iBAAEC,UAAUC,OAAM,YACd,EAAAF,QAAAA,SAAE,cAAcG,GAAG,SAAUZ,IACzBa,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,iCACZC,KAAM,CAAE,EACRC,KAAMT,eAAeU,UACjB,MAAMC,YAAcC,QAAOlB,QAACmB,OAAO,CAE/BC,MAAO,sBACPC,KAAM,GAAGL,SAASM,OAClBC,OAAO,EACPC,eAAe,UAGbP,MAAMQ,OAGZR,MAAMS,UAAUhB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAE6B,iBACFV,MAAMW,SAAS,IAGnBX,MAAMS,UAAUhB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAE6B,iBACFV,MAAMW,SAAS,GAEtB,EACDC,KAAOC,QACH,MAAM,IAAIC,MAAM,yCAAyCC,KAAKC,UAAUH,SAAS,IAEtF,GAEX,GAAE,CACJ"} \ No newline at end of file +{"version":3,"file":"clickStats.min.js","sources":["../src/clickStats.js"],"sourcesContent":["import $ from 'jquery';\nimport Ajax from 'core/ajax';\nimport MyModal from 'block_homework/modals';\n\n/**\n * Homework/amd/src/clickStats.js\n *\n * @package\n * @copyright 2024, cs-24-sw-5-01 \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n *\n */\n\n\n/**\n * Fetches and initializes the completion modal for the homework module that was clicked on.\n * @param stats Array of stats info.\n * @returns {Promise} A promise that, when fulfilled, opens the modal\n */\nexport const init = async(stats) => {\n // Create the modal using block_homework_get_stats_modal\n $(document).ready(function() {\n $('.stats-btn').on('click', () => {\n Ajax.call([{\n methodname: 'block_homework_get_stats_modal',\n args: {'stats': stats},\n done: async function(response) {\n const modal = await MyModal.create({\n // eslint-disable-next-line max-len\n title: \"Your homework stats\",\n body: `${response.html}`,\n large: true,\n removeOnClose: true,\n });\n // Show the modal.\n await modal.show();\n\n // Attach event listeners for buttons\n modal.getRoot().on('click', '[data-action=\"submit\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n\n modal.getRoot().on('click', '[data-action=\"cancel\"]', (e) => {\n e.preventDefault();\n modal.destroy();\n });\n },\n fail: (error) => {\n throw new Error(`Failed to load info homework content: ${JSON.stringify(error)}`);\n }\n }]);\n });\n });\n};"],"names":["_interopRequireDefault","e","__esModule","default","_jquery","_ajax","_modals","_exports","init","async","$","document","ready","on","Ajax","call","methodname","args","stats","done","response","modal","MyModal","create","title","body","html","large","removeOnClose","show","getRoot","preventDefault","destroy","fail","error","Error","JSON","stringify"],"mappings":"sIAE4C,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;;kFAF5CG,QAAAJ,uBAAAI,SACAC,MAAAL,uBAAAK,OACAC,QAAAN,uBAAAM,SAoDEC,SAAAC,KAnCkBC,eAEhB,EAAAC,iBAAEC,UAAUC,OAAM,YACd,EAAAF,QAAAA,SAAE,cAAcG,GAAG,SAAS,KACxBC,MAAIX,QAACY,KAAK,CAAC,CACPC,WAAY,iCACZC,KAAM,CAACC,MAASA,OAChBC,KAAMV,eAAeW,UACjB,MAAMC,YAAcC,QAAOnB,QAACoB,OAAO,CAE/BC,MAAO,sBACPC,KAAM,GAAGL,SAASM,OAClBC,OAAO,EACPC,eAAe,UAGbP,MAAMQ,OAGZR,MAAMS,UAAUjB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAE8B,iBACFV,MAAMW,SAAS,IAGnBX,MAAMS,UAAUjB,GAAG,QAAS,0BAA2BZ,IACnDA,EAAE8B,iBACFV,MAAMW,SAAS,GAEtB,EACDC,KAAOC,QACH,MAAM,IAAIC,MAAM,yCAAyCC,KAAKC,UAAUH,SAAS,IAEtF,GAEX,GAAE,CACJ"} \ No newline at end of file diff --git a/server/moodle/blocks/homework/amd/src/clickInfo.js b/server/moodle/blocks/homework/amd/src/clickInfo.js index a5fb2387..6396e34b 100644 --- a/server/moodle/blocks/homework/amd/src/clickInfo.js +++ b/server/moodle/blocks/homework/amd/src/clickInfo.js @@ -17,7 +17,7 @@ import MyModal from 'block_homework/modals'; * @param userID ID of currently logged-in user. * @returns {Promise} A promise that, when fulfilled, opens the modal */ -export const init = async(userID) => { +export const init = async(userID, readingspeed) => { // Create the modal using block_homework_get_infohomework_modal $(document).ready(function() { $('.timebutton').on('click', (e) => { @@ -25,6 +25,7 @@ export const init = async(userID) => { methodname: 'block_homework_get_infohomework_modal', args: { homeworkID: e.target.id, + readingspeed: readingspeed }, done: async function(response) { const modal = await MyModal.create({ diff --git a/server/moodle/blocks/homework/amd/src/clickStats.js b/server/moodle/blocks/homework/amd/src/clickStats.js index d5e7646b..5b733890 100644 --- a/server/moodle/blocks/homework/amd/src/clickStats.js +++ b/server/moodle/blocks/homework/amd/src/clickStats.js @@ -14,16 +14,16 @@ import MyModal from 'block_homework/modals'; /** * Fetches and initializes the completion modal for the homework module that was clicked on. - * @param userID ID of currently logged-in user. + * @param stats Array of stats info. * @returns {Promise} A promise that, when fulfilled, opens the modal */ -export const init = async(userID) => { +export const init = async(stats) => { // Create the modal using block_homework_get_stats_modal $(document).ready(function() { - $('.stats-btn').on('click', (e) => { + $('.stats-btn').on('click', () => { Ajax.call([{ methodname: 'block_homework_get_stats_modal', - args: {}, + args: {'stats': stats}, done: async function(response) { const modal = await MyModal.create({ // eslint-disable-next-line max-len diff --git a/server/moodle/blocks/homework/block_homework.php b/server/moodle/blocks/homework/block_homework.php index 0b6dd9c5..621015a9 100644 --- a/server/moodle/blocks/homework/block_homework.php +++ b/server/moodle/blocks/homework/block_homework.php @@ -40,6 +40,8 @@ public function get_content() { global $OUTPUT, $DB, $USER; + $stats = $this->getstats(); + // Fetch courses user is enrolled in. $usercourses = enrol_get_users_courses($USER->id, true); @@ -78,10 +80,20 @@ public function get_content() { $tmp['intro'] = strip_tags($homework->intro); $tmp['description'] = ($homework->description); $tmp['courseTitle'] = $DB->get_field('course', 'fullname', ['id' => $homework->course_id]); + $tmp['expectedTime'] = 0; // Retrieving the records of all material of the current homework module. $materialrecords = $DB->get_records('homework_materials', ['homework_id' => $homework->id]); + foreach ($materialrecords as $material) { + if ($material->startime != null && $material->endtime != null) { + $tmp['expectedTime'] += ceil(($material->endtime - $material->starttime)/60); + } + if ($material->startpage != null && $material->endpage != null) { + $tmp['expectedTime'] += ceil(($material->endpage - $material->startpage) * $stats["weightedreadingspeed"]); + } + } + $files = []; // Get ids of homeworkfiles. @@ -141,8 +153,8 @@ public function get_content() { $this->page->requires->js_call_amd('block_homework/homework_injector', 'init', [$homeworks]); $this->page->requires->js_call_amd('block_homework/map_link_injector', 'init'); $this->page->requires->js_call_amd('block_homework/filter', 'init'); - $this->page->requires->js_call_amd('block_homework/clickInfo', 'init', [$USER->id]); - $this->page->requires->js_call_amd('block_homework/clickStats', 'init'); + $this->page->requires->js_call_amd('block_homework/clickInfo', 'init', [$USER->id, $stats['weightedreadingspeed']]); + $this->page->requires->js_call_amd('block_homework/clickStats', 'init', [$stats]); return $this->content; } @@ -180,4 +192,84 @@ public function applicable_formats(): array { 'my' => true, ]; } -} + + public function getstats() { + global $DB, $USER; + + // The weight indicates the number of minutes after which the user's reading speed will be prioritized over the average. + $weight = 180; + // The global reading speed in minutes. + $globalreadingspeed = 2; + + // Get records of all completions with the start page, end page, start time and end time of the material. + $records = $DB->get_records_sql( + " + SELECT c.*, hm.startpage, hm.endpage + FROM {completions} c + LEFT JOIN {homework_materials} hm ON c.material_id = hm.id + WHERE c.usermodified = :userid", + ['userid' => $USER->id] + ); + + // Fetch courses user is enrolled in. + $usercourses = enrol_get_users_courses($USER->id, true); + + $courseids = array_keys($usercourses); // Extract course IDs from the user's courses array. + + $placeholders = implode(',', array_fill(0, count($courseids), '?')); + + $sql = " + SELECT hm.* + FROM {homework_materials} hm + INNER JOIN {homework} hw ON hm.homework_id = hw.id + INNER JOIN {course} c ON hw.course_id = c.id + WHERE c.id IN ($placeholders) + "; + + $availablematerials = $DB->get_records_sql($sql, $courseids); + + $totalminutes = 0; + $totalreadingtime = 0; + $totalpages = 0; + $totaldays = 0; + + foreach ($records as $record) { + // Timestamps are in seconds, so we get the day difference by dividing by seconds per day. + // Use the time from the first homework completion as the start time for these stats. + $totaldays = floor((time() - $record->timecreated) / 86400) + 1; + + $totalminutes += $record->timetaken; + + $startpage = $record->startpage; + $endpage = $record->endpage; + + if ($startpage != null && $endpage != null) { + $totalpages += $endpage - $startpage; + $totalreadingtime += $record->timetaken; + } + } + + $weightedreadingspeed = $globalreadingspeed; + + $timeperday = 0; + if ($totaldays != 0) { + $timeperday = $totalminutes / $totaldays; + } + + if ($totalpages != 0) { + $readingspeed = $totalreadingtime / $totalpages; + // The reading speed is weighted. When no pages have been read, it will be the global average a page per minute. + // Once the number of minutes reaches the weight, the user's speed will be weighted more than the average. + $weightedreadingspeed = $globalreadingspeed + ($readingspeed - $globalreadingspeed) * + $totalminutes / ($totalminutes + $weight); + } + + $percentcompleted = 0; + if (count($records) && count($availablematerials)) { + $percentcompleted = count($records) / count($availablematerials) * 100; + } + + return ['timeperday' => $timeperday, 'percentcompleted' => $percentcompleted, 'weightedreadingspeed' => $weightedreadingspeed]; + } + +} \ No newline at end of file diff --git a/server/moodle/blocks/homework/classes/external/get_infohomework_modal.php b/server/moodle/blocks/homework/classes/external/get_infohomework_modal.php index aa3ae85a..406d434b 100644 --- a/server/moodle/blocks/homework/classes/external/get_infohomework_modal.php +++ b/server/moodle/blocks/homework/classes/external/get_infohomework_modal.php @@ -42,6 +42,7 @@ class get_infohomework_modal extends external_api { public static function execute_parameters(): external_function_parameters { return new external_function_parameters([ 'homeworkID' => new external_value(PARAM_INT, 'The ID of the homework item'), + 'readingspeed' => new external_value(PARAM_FLOAT, "The user's reading speed"), ]); } @@ -52,7 +53,7 @@ public static function execute_parameters(): external_function_parameters { * @return string[] - The HTML to be shown client-side * @throws dml_exception|JsonException */ - public static function execute(int $homeworkid): array { + public static function execute(int $homeworkid, float $readingspeed): array { global $DB, $USER; $homework = $DB->get_record('homework', ['id' => $homeworkid]); $course = $DB->get_record('course', ['id' => $homework->course_id]); @@ -76,6 +77,7 @@ public static function execute(int $homeworkid): array { if ($material->file_id !== null) { $material->fileurl = self::get_file_link_by_id($material->file_id); } + $material->expectedTime = ceil(($material->endpage - $material->startpage) * $readingspeed); $literaturearray[] = $material; } else if ($material->link !== null) { $linksarray[] = $material; @@ -85,6 +87,9 @@ public static function execute(int $homeworkid): array { } $videosarray[] = $material; } + if ($material->starttime != null && $material->endtime != null) { + $material->expectedTime = ceil(($material->endtime - $material->starttime)/60); + } } return self::get_info($homework, $course, $literaturearray, $linksarray, $videosarray); diff --git a/server/moodle/blocks/homework/classes/external/get_stats_modal.php b/server/moodle/blocks/homework/classes/external/get_stats_modal.php index b1d3f4cb..2d9314f8 100644 --- a/server/moodle/blocks/homework/classes/external/get_stats_modal.php +++ b/server/moodle/blocks/homework/classes/external/get_stats_modal.php @@ -20,11 +20,13 @@ global $CFG; use coding_exception; +use core\router\schema\objects\array_of_things; use core_external\external_api; use dml_exception; use core_external\external_function_parameters; use core_external\external_value; use core_external\external_single_structure; +use core_external\external_multiple_structure; use JsonException; use Mustache_Engine; @@ -40,81 +42,30 @@ class get_stats_modal extends external_api { * @return external_function_parameters */ public static function execute_parameters(): external_function_parameters { - return new external_function_parameters([]); + return new external_function_parameters([ + 'stats' => new external_single_structure([ + 'timeperday' => new external_value(PARAM_FLOAT, 'Time spent on homework per day'), + 'weightedreadingspeed' => new external_value(PARAM_FLOAT, 'Weighted reading speed average'), + 'percentcompleted' => new external_value(PARAM_FLOAT, 'Percent of homework completed'), + ]), + ]); } /** * Generates the custom HTML for the homework chooser modal. * - * @param int $homeworkID The ID of the homework item + * @param array_of_things $stats The stats array * @return string[] - The HTML to be shown client-side * @throws dml_exception|JsonException */ - public static function execute(): array { - global $DB, $USER; - - // The weight indicates the number of minutes after which the user's reading speed will be prioritized over the average. - $weight = 180; - // The global reading speed in minutes. - $globalreadingspeed = 2; - - $records = $DB->get_records_sql( - " - SELECT c.*, hm.startpage, hm.endpage - FROM {completions} c - LEFT JOIN {homework_materials} hm ON c.material_id = hm.id - WHERE c.usermodified = :userid", - ['userid' => $USER->id] - ); - - $availablematerials = $DB->get_records('homework_materials'); - - $totalminutes = 0; - $totalreadingtime = 0; - $totalpages = 0; - $totaldays = 0; - - foreach ($records as $record) { - // Timestamps are in seconds, so we get the day difference by dividing by seconds per day. - // Use the time from the first homework completion as the start time for these stats. - $totaldays = floor((time() - $record->timecreated) / 86400) + 1; - - $totalminutes += $record->timetaken; - - $startpage = $record->startpage; - $endpage = $record->endpage; - - if ($startpage != null && $endpage != null) { - $totalpages += $endpage - $startpage; - $totalreadingtime += $record->timetaken; - } - } - $weightedreadingspeed = $globalreadingspeed; - $timeperday = 0; - if ($totaldays != 0) { - $timeperday = $totalminutes / $totaldays; - } - - if ($totalpages != 0) { - $readingspeed = $totalreadingtime / $totalpages; - // The reading speed is weighted. When no pages have been read, it will be the global average a page per minute. - // Once the number of minutes reaches the weight, the user's speed will be weighted more than the average. - $weightedreadingspeed = $globalreadingspeed + ($readingspeed - $globalreadingspeed) * - $totalminutes / ($totalminutes + $weight); - } - - $percentcompleted = 0; - if (count($records) && count($availablematerials)) { - $percentcompleted = count($records) / count($availablematerials) * 100; - } - + public static function execute($stats): array { $mustache = new Mustache_Engine(); // Prepare data for the template. $content = [ - 'weightedreadingspeed' => round($weightedreadingspeed, 2), - 'percentcompleted' => round($percentcompleted, 2), - 'timeperday' => round($timeperday, 2), + 'weightedreadingspeed' => round($stats['weightedreadingspeed'], 2), + 'percentcompleted' => round($stats['percentcompleted'], 2), + 'timeperday' => round($stats['timeperday'], 2), ]; $templatepath = __DIR__ . "/../../templates/stats.mustache"; diff --git a/server/moodle/blocks/homework/templates/data.mustache b/server/moodle/blocks/homework/templates/data.mustache index f6b94137..01e6d5fc 100644 --- a/server/moodle/blocks/homework/templates/data.mustache +++ b/server/moodle/blocks/homework/templates/data.mustache @@ -44,6 +44,7 @@

{{courseTitle}}

{{name}}

{{duedate}}

+

Expected time: {{expectedTime}} minutes

{{intro}}

{{#files}} diff --git a/server/moodle/blocks/homework/templates/timeinfotemplate.mustache b/server/moodle/blocks/homework/templates/timeinfotemplate.mustache index 1fa9e0c3..4856b323 100644 --- a/server/moodle/blocks/homework/templates/timeinfotemplate.mustache +++ b/server/moodle/blocks/homework/templates/timeinfotemplate.mustache @@ -9,6 +9,7 @@
{{description}} +

Expected time: {{expectedTime}} minutes

@@ -19,6 +20,7 @@