Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"version":3,"file":"edit_penalty_form.min.js","sources":["../src/edit_penalty_form.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Handles edit penalty form.\n *\n * @module     gradepenalty_duedate/edit_penalty_form\n * @copyright  2024 Catalyst IT\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport * as notification from 'core/notification';\nimport Fragment from 'core/fragment';\nimport Templates from 'core/templates';\n\n/**\n * Rule js class.\n */\nclass PenaltyRule {\n    constructor(\n        overdueby = 0,\n        penalty = 0,\n    ) {\n        this.overdueby = overdueby;\n        this.penalty = penalty;\n    }\n}\n\n/**\n * Selectors\n */\nconst SELECTORS = {\n    FORM_CONTAINER: '#penalty_rule_form_container',\n    ACTION_MENU: '.action-menu',\n    ADD_BUTTON: '#addrulebutton',\n    INSERT_BUTTON: '.insertbelow',\n    DELETE_BUTTON: '.deleterulebuttons',\n    DELETE_ALL_BUTTON_CONTAINER: '#deleteallrulesbuttoncontainer',\n};\n\n/**\n * Register click event for delete and insert buttons.\n */\nconst registerEventListeners = () => {\n    // Find all action menus in penalty rule form.\n    const container = document.querySelector(SELECTORS.FORM_CONTAINER);\n    container.addEventListener('click', (e) => {\n        if (e.target.closest(SELECTORS.DELETE_BUTTON)) {\n            e.preventDefault();\n            deleteRule(e.target);\n\n            return;\n        }\n\n        if (e.target.closest(SELECTORS.INSERT_BUTTON)) {\n            e.preventDefault();\n            insertRule(e.target);\n\n            return;\n        }\n    });\n\n    document.querySelector(SELECTORS.ADD_BUTTON).addEventListener('click', (e) => {\n        e.preventDefault();\n        insertRuleAtIndex(container.querySelectorAll(SELECTORS.ACTION_MENU).length);\n\n        return;\n    });\n};\n\n/**\n * Delete a rule group represented by thenode.\n *\n * @param {NodeElement} target\n */\nconst deleteRule = (target) => {\n    // Get all form data.\n    const {contextid, penaltyRules, finalPenaltyRule} = buildFormParams();\n    const ruleNumber = getRuleNumber(target);\n\n    // Remove the penalty rule.\n    const updatedPenaltyRules = penaltyRules.filter((rule, index) => index !== ruleNumber);\n\n    loadPenaltyRuleForm(\n        contextid,\n        updatedPenaltyRules,\n        finalPenaltyRule,\n    );\n};\n\n/**\n * Insert a rule group below the clicked button.\n *\n * @param {NodeElement} target\n */\nconst insertRule = (target) => insertRuleAtIndex(getRuleNumber(target) + 1);\n\n/**\n * Add a new rule group at the specified index.\n *\n * @param {Number} ruleNumber\n */\nconst insertRuleAtIndex = (ruleNumber) => {\n    // Get all form data.\n    const {contextid, penaltyRules, finalPenaltyRule} = buildFormParams();\n\n    // Insert a new penalty rule.\n    penaltyRules.splice(ruleNumber, 0, new PenaltyRule());\n\n    loadPenaltyRuleForm(\n        contextid,\n        penaltyRules,\n        finalPenaltyRule,\n    );\n};\n\n/**\n * Get the rule number from the target.\n *\n * @param {Object} target\n * @return {Number} rule number\n */\nconst getRuleNumber = (target) => {\n    const allRules = target\n        .closest(SELECTORS.FORM_CONTAINER)\n        .querySelectorAll(SELECTORS.ACTION_MENU);\n\n    const foundIndex = Array.prototype.findIndex.call(\n        allRules,\n        (element) => element.contains(target),\n    );\n\n    if (foundIndex === -1) {\n        throw new Error('Rule number not found on target', target);\n    }\n\n    return foundIndex;\n};\n\n/**\n * Build form parameters for loading fragment.\n *\n * @return {Object} form params\n */\nconst buildFormParams = () => {\n    // Get the penalty rule form in its container.\n    const container = document.querySelector(SELECTORS.FORM_CONTAINER);\n    const form = container.querySelector('form');\n\n    // Get all form data\n    const formData = new FormData(form);\n\n    // Get context id.\n    const contextid = formData.get('contextid');\n\n    // Get group count.\n    const groupCount = formData.get('rulegroupcount');\n\n    // Create list of penalty rules.\n    const penaltyRules = [];\n\n    // Current penalty rules.\n\n    for (let i = 0; i < groupCount; i++) {\n        penaltyRules.push(new PenaltyRule(\n            formData.get(`overdueby[${i}][number]`) * formData.get(`overdueby[${i}][timeunit]`),\n            formData.get(`penalty[${i}]`)\n        ));\n    }\n\n    return {\n        contextid,\n        penaltyRules,\n        finalPenaltyRule: formData.get('finalpenaltyrule'),\n    };\n};\n\n/**\n * Load the penalty rule form.\n *\n * @param {Number} contextId\n * @param {Array} penaltyRules\n * @param {Number} finalPenaltyRule\n */\nconst loadPenaltyRuleForm = (\n    contextId,\n    penaltyRules,\n    finalPenaltyRule,\n) => {\n    // Disable the form while loading to improve UX.\n    const container = document.querySelector(SELECTORS.FORM_CONTAINER);\n    const form = container.querySelector('form');\n    form.querySelectorAll('input, select').forEach(input => {\n        input.disabled = true;\n    });\n\n    // Disable the add rule button.\n    const addButton = document.querySelector(SELECTORS.ADD_BUTTON);\n    if (addButton) {\n        addButton.disabled = true;\n    }\n\n    // Disable the delete all rules button.\n    const deleteAllButton = document.querySelector(SELECTORS.DELETE_ALL_BUTTON_CONTAINER).querySelector('button');\n    if (deleteAllButton) {\n        deleteAllButton.disabled = true;\n    }\n\n    // Replace the form with the new form.\n    Fragment.loadFragment(\n        'gradepenalty_duedate',\n        'penalty_rule_form',\n        contextId,\n        {\n            penaltyrules: JSON.stringify(penaltyRules),\n            finalpenaltyrule: finalPenaltyRule,\n        },\n    )\n        .then((html, js) => {\n            Templates.replaceNodeContents(document.querySelector(SELECTORS.FORM_CONTAINER), html, js);\n\n            if (addButton) {\n                addButton.disabled = false;\n            }\n\n            if (deleteAllButton) {\n                deleteAllButton.disabled = false;\n            }\n            return;\n        })\n        .catch(notification.exception);\n\n\n};\n\n/**\n * Initialize the js.\n */\nexport const init = () => {\n    registerEventListeners();\n};\n"],"names":["PenaltyRule","constructor","overdueby","penalty","SELECTORS","deleteRule","target","contextid","penaltyRules","finalPenaltyRule","buildFormParams","ruleNumber","getRuleNumber","updatedPenaltyRules","filter","rule","index","loadPenaltyRuleForm","insertRule","insertRuleAtIndex","splice","allRules","closest","querySelectorAll","foundIndex","Array","prototype","findIndex","call","element","contains","Error","form","document","querySelector","formData","FormData","get","groupCount","i","push","contextId","forEach","input","disabled","addButton","deleteAllButton","loadFragment","penaltyrules","JSON","stringify","finalpenaltyrule","then","html","js","replaceNodeContents","catch","notification","exception","container","addEventListener","e","preventDefault","length","registerEventListeners"],"mappings":";;;;;;;oHA8BMA,YACFC,kBACIC,iEAAY,EACZC,+DAAU,OAELD,UAAYA,eACZC,QAAUA,eAOjBC,yBACc,+BADdA,sBAEW,eAFXA,qBAGU,iBAHVA,wBAIa,eAJbA,wBAKa,qBALbA,sCAM2B,iCAsC3BC,WAAcC,eAEVC,UAACA,UAADC,aAAYA,aAAZC,iBAA0BA,kBAAoBC,kBAC9CC,WAAaC,cAAcN,QAG3BO,oBAAsBL,aAAaM,QAAO,CAACC,KAAMC,QAAUA,QAAUL,aAE3EM,oBACIV,UACAM,oBACAJ,mBASFS,WAAcZ,QAAWa,kBAAkBP,cAAcN,QAAU,GAOnEa,kBAAqBR,mBAEjBJ,UAACA,UAADC,aAAYA,aAAZC,iBAA0BA,kBAAoBC,kBAGpDF,aAAaY,OAAOT,WAAY,EAAG,IAAIX,aAEvCiB,oBACIV,UACAC,aACAC,mBAUFG,cAAiBN,eACbe,SAAWf,OACZgB,QAAQlB,0BACRmB,iBAAiBnB,uBAEhBoB,WAAaC,MAAMC,UAAUC,UAAUC,KACzCP,UACCQ,SAAYA,QAAQC,SAASxB,cAGd,IAAhBkB,iBACM,IAAIO,MAAM,kCAAmCzB,eAGhDkB,YAQLd,gBAAkB,WAGdsB,KADYC,SAASC,cAAc9B,0BAClB8B,cAAc,QAG/BC,SAAW,IAAIC,SAASJ,MAGxBzB,UAAY4B,SAASE,IAAI,aAGzBC,WAAaH,SAASE,IAAI,kBAG1B7B,aAAe,OAIhB,IAAI+B,EAAI,EAAGA,EAAID,WAAYC,IAC5B/B,aAAagC,KAAK,IAAIxC,YAClBmC,SAASE,wBAAiBE,gBAAgBJ,SAASE,wBAAiBE,kBACpEJ,SAASE,sBAAeE,gBAIzB,CACHhC,UAAAA,UACAC,aAAAA,aACAC,iBAAkB0B,SAASE,IAAI,sBAWjCpB,oBAAsB,CACxBwB,UACAjC,aACAC,oBAGkBwB,SAASC,cAAc9B,0BAClB8B,cAAc,QAChCX,iBAAiB,iBAAiBmB,SAAQC,QAC3CA,MAAMC,UAAW,WAIfC,UAAYZ,SAASC,cAAc9B,sBACrCyC,YACAA,UAAUD,UAAW,SAInBE,gBAAkBb,SAASC,cAAc9B,uCAAuC8B,cAAc,UAChGY,kBACAA,gBAAgBF,UAAW,qBAItBG,aACL,uBACA,oBACAN,UACA,CACIO,aAAcC,KAAKC,UAAU1C,cAC7B2C,iBAAkB1C,mBAGrB2C,MAAK,CAACC,KAAMC,yBACCC,oBAAoBtB,SAASC,cAAc9B,0BAA2BiD,KAAMC,IAElFT,YACAA,UAAUD,UAAW,GAGrBE,kBACAA,gBAAgBF,UAAW,MAIlCY,MAAMC,aAAaC,0BAQR,KAnMW,YAErBC,UAAY1B,SAASC,cAAc9B,0BACzCuD,UAAUC,iBAAiB,SAAUC,GAC7BA,EAAEvD,OAAOgB,QAAQlB,0BACjByD,EAAEC,sBACFzD,WAAWwD,EAAEvD,SAKbuD,EAAEvD,OAAOgB,QAAQlB,0BACjByD,EAAEC,sBACF5C,WAAW2C,EAAEvD,kBAMrB2B,SAASC,cAAc9B,sBAAsBwD,iBAAiB,SAAUC,IACpEA,EAAEC,iBACF3C,kBAAkBwC,UAAUpC,iBAAiBnB,uBAAuB2D,YA+KxEC"}