Proyectos de Subversion Moodle

Rev

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

{"version":3,"file":"edit_multiple_grades.min.js","sources":["../src/edit_multiple_grades.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 * JavaScript for managing multiple grade items for a quiz.\n *\n * @module     mod_quiz/edit_multiple_grades\n * @copyright  2023 The Open University\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {call as fetchMany} from 'core/ajax';\nimport MoodleConfig from 'core/config';\nimport {addIconToContainer} from 'core/loadingicon';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\nimport {get_string as getString} from 'core/str';\nimport {render as renderTemplate} from 'core/templates';\nimport {replaceNode} from 'core/templates';\n\n/**\n * @type {Object} selectors used in this code.\n */\nconst SELECTORS = {\n    'addGradeItemButton': '#mod_quiz-add_grade_item',\n    'autoSetupButton': '#mod_quiz-grades_auto_setup',\n    'editingPageContents': '#edit_grading_page-contents',\n    'gradeItemList': 'table#mod_quiz-grade-item-list',\n    'gradeItemSelect': 'select[data-slot-id]',\n    'gradeItemSelectId': (id) => 'select#grade-item-choice-' + id,\n    'gradeItemTr': 'table#mod_quiz-grade-item-list tr[data-quiz-grade-item-id]',\n    'inplaceEditable': 'span.inplaceeditable',\n    'inplaceEditableOn': 'span.inplaceeditable.inplaceeditingon',\n    'resetAllButton': '#mod_quiz-grades_reset_all',\n    'slotList': 'table#mod_quiz-slot-list',\n    'updateGradeItemLink': (id) => 'tr[data-quiz-grade-item-id=\"' + id + '\"] .quickeditlink',\n};\n\n/**\n * Call the Ajax service to create a quiz grade item.\n *\n * @param {Number} quizId id of the quiz to update.\n * @returns {Promise<Object>} a promise that resolves to the template context required to re-render the page.\n */\nconst createGradeItem = (\n    quizId,\n) => callServiceAndReturnRenderingData({\n    methodname: 'mod_quiz_create_grade_items',\n    args: {\n        quizid: quizId,\n        quizgradeitems: [{name: ''}],\n    }\n});\n\n/**\n * Call the Ajax service to update a quiz grade item.\n *\n * @param {Number} quizId id of the quiz to update.\n * @param {Number} gradeItemId id of the grade item to update.\n * @param {String} newName the new name to set.\n * @return {Promise} Promise that resolves to the context required to re-render the page.\n */\nconst updateGradeItem = (\n    quizId,\n    gradeItemId,\n    newName\n) => callServiceAndReturnRenderingData({\n    methodname: 'mod_quiz_update_grade_items',\n    args: {\n        quizid: quizId,\n        quizgradeitems: [{id: gradeItemId, name: newName}],\n    }\n});\n\n/**\n * Call the Ajax service to delete a quiz grade item.\n *\n * @param {Number} quizId id of the quiz to update.\n * @param {Number} gradeItemId id of the grade item to delete.\n * @return {Promise} Promise that resolves to the context required to re-render the page.\n */\nconst deleteGradeItem = (\n    quizId,\n    gradeItemId\n) => callServiceAndReturnRenderingData({\n    methodname: 'mod_quiz_delete_grade_items',\n    args: {\n        quizid: quizId,\n        quizgradeitems: [{id: gradeItemId}],\n    }\n});\n\n/**\n * Call the Ajax service to update the quiz grade item used by a slot.\n *\n * @param {Number} quizId id of the quiz to update.\n * @param {Number} slotId id of the slot to update.\n * @param {Number|null} gradeItemId new grade item ot set, or null to un-set.\n * @return {Promise} Promise that resolves to the context required to re-render the page.\n */\nconst updateSlotGradeItem = (\n    quizId,\n    slotId,\n    gradeItemId\n) => callServiceAndReturnRenderingData({\n    methodname: 'mod_quiz_update_slots',\n    args: {\n        quizid: quizId,\n        slots: [{id: slotId, quizgradeitemid: gradeItemId}],\n    }\n});\n\n/**\n * Call the Ajax service to setup one grade item for each quiz section.\n *\n * @param {Number} quizId id of the quiz to update.\n * @return {Promise} Promise that resolves to the context required to re-render the page.\n */\nconst autoSetupGradeItems = (\n    quizId\n) => callServiceAndReturnRenderingData({\n    methodname: 'mod_quiz_create_grade_item_per_section',\n    args: {\n        quizid: quizId\n    }\n});\n\n/**\n * Make a web service call, and also call mod_quiz_get_edit_grading_page_data to get the date to re-render the page.\n *\n * @param {Object} methodCall a web service call to pass to fetchMany. Must include methodCall.args.quizid.\n * @returns {Promise<Object>} a promise that resolves to the template context required to re-render the page.\n */\nconst callServiceAndReturnRenderingData = (methodCall) => callServicesAndReturnRenderingData([methodCall]);\n\n/**\n * Make a web service call, and also call mod_quiz_get_edit_grading_page_data to get the date to re-render the page.\n *\n * @param {Object[]} methodCalls web service calls to pass to fetchMany. Must include methodCalls[0].args.quizid.\n * @returns {Promise<Object>} a promise that resolves to the template context required to re-render the page.\n */\nconst callServicesAndReturnRenderingData = (methodCalls) => {\n    methodCalls.push({\n            methodname: 'mod_quiz_get_edit_grading_page_data',\n            args: {\n                quizid: methodCalls[0].args.quizid,\n            }\n        });\n    return Promise.all(fetchMany(methodCalls))\n    .then(results => JSON.parse(results.at(-1)));\n};\n\n/**\n * Handle click events on the delete icon.\n *\n * @param {Event} e click event.\n */\nconst handleGradeItemDelete = (e) => {\n    e.preventDefault();\n    const pending = new Pending('delete-quiz-grade-item');\n\n    const tableCell = e.target.closest('td');\n    addIconToContainer(tableCell, pending);\n\n    const tableRow = tableCell.closest('tr');\n    const quizId = tableRow.closest('table').dataset.quizId;\n    const gradeItemId = tableRow.dataset.quizGradeItemId;\n\n    let nextItemToFocus;\n    if (tableRow.nextElementSibling) {\n        nextItemToFocus = SELECTORS.updateGradeItemLink(tableRow.nextElementSibling.dataset.quizGradeItemId);\n    } else {\n        nextItemToFocus = SELECTORS.addGradeItemButton;\n    }\n\n    deleteGradeItem(quizId, gradeItemId)\n        .then(reRenderPage)\n        .then(() => {\n            pending.resolve();\n            document.querySelector(nextItemToFocus).focus();\n        })\n        .catch(Notification.exception);\n};\n\n/**\n *\n * @param {HTMLElement} editableSpan the editable to turn off.\n */\nconst stopEditingGadeItem = (editableSpan) => {\n    editableSpan.innerHTML = editableSpan.dataset.oldContent;\n    delete editableSpan.dataset.oldContent;\n\n    editableSpan.classList.remove('inplaceeditingon');\n    editableSpan.querySelector('[data-action-edit]').focus();\n};\n\n/**\n * Handle click events on the start rename icon.\n *\n * @param {Event} e click event.\n */\nconst handleGradeItemEditStart = (e) => {\n    e.preventDefault();\n    const pending = new Pending('edit-quiz-grade-item-start');\n    const editableSpan = e.target.closest(SELECTORS.inplaceEditable);\n\n    document.querySelectorAll(SELECTORS.inplaceEditableOn).forEach(stopEditingGadeItem);\n\n    editableSpan.dataset.oldContent = editableSpan.innerHTML;\n    getString('edittitleinstructions')\n        .then((instructions) => {\n            const uniqueId = 'gi-edit-input-' + editableSpan.closest('tr').dataset.quizGradeItemId;\n            editableSpan.innerHTML = '<span class=\"editinstructions\">' + instructions + '</span>' +\n                    '<label class=\"sr-only\" for=\"' + uniqueId + '\">' + editableSpan.dataset.editLabel + '</label>' +\n                    '<input type=\"text\" id=\"' + uniqueId + '\" value=\"' + editableSpan.dataset.rawName +\n                            '\" class=\"ignoredirty form-control w-100\">';\n\n            const inputElement = editableSpan.querySelector('input');\n            inputElement.focus();\n            inputElement.select();\n            editableSpan.classList.add('inplaceeditingon');\n            pending.resolve();\n            return null;\n        })\n        .catch(Notification.exception);\n};\n\n/**\n * Handle key down in the editable.\n *\n * @param {Event} e key event.\n */\nconst handleGradeItemKeyDown = (e) => {\n    if (e.keyCode !== 13) {\n        return;\n    }\n\n    const editableSpan = e.target.closest(SELECTORS.inplaceEditableOn);\n\n    // Check this click is on a relevant element.\n    if (!editableSpan || !editableSpan.closest(SELECTORS.gradeItemList)) {\n        return;\n    }\n\n    e.preventDefault();\n    const pending = new Pending('edit-quiz-grade-item-save');\n\n    const newName = editableSpan.querySelector('input').value;\n    const tableCell = e.target.closest('th');\n    addIconToContainer(tableCell);\n\n    const tableRow = tableCell.closest('tr');\n    const quizId = tableRow.closest('table').dataset.quizId;\n    const gradeItemId = tableRow.dataset.quizGradeItemId;\n\n    updateGradeItem(quizId, gradeItemId, newName)\n        .then(reRenderPage)\n        .then(() => {\n            pending.resolve();\n            document.querySelector(SELECTORS.updateGradeItemLink(gradeItemId)).focus({'focusVisible': true});\n        })\n        .catch(Notification.exception);\n};\n\n/**\n * Replace the contents of the page with the page re-rendered from the provided data, once that promise resolves.\n *\n * @param {Object} editGradingPageData the template context data required to re-render the page.\n * @returns {Promise<void>} a promise that will resolve when the page is updated.\n */\nconst reRenderPage = (editGradingPageData) =>\n    renderTemplate('mod_quiz/edit_grading_page', editGradingPageData)\n        .then((html, js) => replaceNode(document.querySelector(SELECTORS.editingPageContents), html, js || ''));\n\n/**\n * Handle key up in the editable.\n *\n * @param {Event} e key event.\n */\nconst handleGradeItemKeyUp = (e) => {\n    if (e.keyCode !== 27) {\n        return;\n    }\n\n    const editableSpan = e.target.closest(SELECTORS.inplaceEditableOn);\n\n    // Check this click is on a relevant element.\n    if (!editableSpan || !editableSpan.closest(SELECTORS.gradeItemList)) {\n        return;\n    }\n\n    e.preventDefault();\n    stopEditingGadeItem(editableSpan);\n};\n\n/**\n * Handle focus out of the editable.\n *\n * @param {Event} e event.\n */\nconst handleGradeItemFocusOut = (e) => {\n    if (MoodleConfig.behatsiterunning) {\n        // Behat triggers focusout too often so ignore.\n        return;\n    }\n\n    const editableSpan = e.target.closest(SELECTORS.inplaceEditableOn);\n\n    // Check this click is on a relevant element.\n    if (!editableSpan || !editableSpan.closest(SELECTORS.gradeItemList)) {\n        return;\n    }\n\n    e.preventDefault();\n    stopEditingGadeItem(editableSpan);\n};\n\n/**\n * Handle when the selected grade item for a slot is changed.\n *\n * @param {Event} e event.\n */\nconst handleSlotGradeItemChanged = (e) => {\n    const select = e.target.closest(SELECTORS.gradeItemSelect);\n\n    // Check this click is on a relevant element.\n    if (!select || !select.closest(SELECTORS.slotList)) {\n        return;\n    }\n\n    e.preventDefault();\n    const pending = new Pending('edit-slot-grade-item-updated');\n\n    const slotId = select.dataset.slotId;\n    const newGradeItemId = select.value ? select.value : null;\n    const tableCell = e.target.closest('td');\n    addIconToContainer(tableCell, pending);\n\n    const quizId = tableCell.closest('table').dataset.quizId;\n\n    updateSlotGradeItem(quizId, slotId, newGradeItemId)\n        .then(reRenderPage)\n        .then(() => {\n            pending.resolve();\n            document.querySelector(SELECTORS.gradeItemSelectId(slotId)).focus();\n        })\n        .catch(Notification.exception);\n};\n\n/**\n * Handle clicks in the table the shows the grade items.\n *\n * @param {Event} e click event.\n */\nconst handleGradeItemClick = (e) => {\n    const link = e.target.closest('a');\n\n    // Check this click is on a relevant element.\n    if (!link || !link.closest(SELECTORS.gradeItemList)) {\n        return;\n    }\n\n    if (link.dataset.actionDelete) {\n        handleGradeItemDelete(e);\n    }\n\n    if (link.dataset.actionEdit) {\n        handleGradeItemEditStart(e);\n    }\n};\n\n/**\n * Handle clicks on the buttons.\n *\n * @param {Event} e click event.\n */\n\nconst handleButtonClick = (e) => {\n    if (e.target.closest(SELECTORS.addGradeItemButton)) {\n        handleAddGradeItemClick(e);\n    }\n    if (e.target.closest(SELECTORS.autoSetupButton)) {\n        handleAutoSetup(e);\n    }\n    if (e.target.closest(SELECTORS.resetAllButton)) {\n        handleResetAllClick(e);\n    }\n};\n\n/**\n * Handle clicks on the 'Add grade item' button.\n *\n * @param {Event} e click event.\n */\nconst handleAddGradeItemClick = (e) => {\n    e.preventDefault();\n    const pending = new Pending('create-quiz-grade-item');\n    addIconToContainer(e.target.parentNode, pending);\n\n    const quizId = e.target.dataset.quizId;\n\n    createGradeItem(quizId)\n        .then(reRenderPage)\n        .then(() => {\n            pending.resolve();\n            document.querySelector(SELECTORS.addGradeItemButton).focus();\n        })\n        .catch(Notification.exception);\n};\n\n/**\n * Handle clicks on the reset button - show a confirmation.\n *\n * @param {Event} e click event.\n */\nconst handleAutoSetup = (e) => {\n    e.preventDefault();\n    const pending = new Pending('setup-quiz-grade-items');\n\n    const quizId = e.target.dataset.quizId;\n\n    autoSetupGradeItems(quizId)\n        .then(reRenderPage)\n        .then(() => {\n            pending.resolve();\n            document.querySelector(SELECTORS.resetAllButton).focus();\n        })\n        .catch(Notification.exception);\n};\n\n/**\n * Handle clicks on the reset button - show a confirmation.\n *\n * @param {Event} e click event.\n */\nconst handleResetAllClick = (e) => {\n    e.preventDefault();\n    const button = e.target;\n\n    Notification.deleteCancelPromise(\n        getString('gradeitemsremoveallconfirm', 'quiz'),\n        getString('gradeitemsremoveallmessage', 'quiz'),\n        getString('reset'),\n        button\n    ).then(() => reallyResetAll(button))\n    .catch(() => button.focus());\n};\n\n/**\n * Really reset all if the confirmation is OKed.\n *\n * @param {HTMLElement} button the reset button.\n */\nconst reallyResetAll = (button) => {\n    const pending = new Pending('reset-quiz-grading');\n    addIconToContainer(button.parentNode, pending);\n\n    const quizId = button.dataset.quizId;\n\n    let methodCalls = [];\n\n    // Call to clear any assignments of grade items to slots (if required).\n    const slotResets = [...document.querySelectorAll(SELECTORS.gradeItemSelect)].map(\n            (select) => ({\n                id: select.dataset.slotId,\n                quizgradeitemid: 0,\n            }));\n    if (slotResets.length) {\n        methodCalls.push({\n            methodname: 'mod_quiz_update_slots',\n            args: {\n                quizid: quizId,\n                slots: slotResets\n            }\n        });\n    }\n\n    // Request to delete all the grade items.\n    methodCalls.push({\n        methodname: 'mod_quiz_delete_grade_items',\n        args: {\n            quizid: quizId,\n            quizgradeitems: [...document.querySelectorAll(SELECTORS.gradeItemTr)].map((tr) => {\n                return {id: tr.dataset.quizGradeItemId};\n            })\n        }\n    });\n\n    callServicesAndReturnRenderingData(methodCalls)\n        .then(reRenderPage)\n        .then(() => {\n            pending.resolve();\n            document.querySelector(SELECTORS.addGradeItemButton).focus();\n        })\n        .catch(Notification.exception);\n};\n\n/**\n * Replace the container with a new version.\n */\nconst registerEventListeners = () => {\n    document.body.addEventListener('click', handleGradeItemClick);\n    document.body.addEventListener('keydown', handleGradeItemKeyDown);\n    document.body.addEventListener('keyup', handleGradeItemKeyUp);\n    document.body.addEventListener('focusout', handleGradeItemFocusOut);\n\n    document.body.addEventListener('click', handleButtonClick);\n\n    document.body.addEventListener('change', handleSlotGradeItemChanged);\n};\n\n/**\n * Entry point.\n */\nexport const init = () => {\n    registerEventListeners();\n};\n"],"names":["SELECTORS","id","callServiceAndReturnRenderingData","methodCall","callServicesAndReturnRenderingData","methodCalls","push","methodname","args","quizid","Promise","all","then","results","JSON","parse","at","handleGradeItemDelete","e","preventDefault","pending","Pending","tableCell","target","closest","tableRow","quizId","dataset","gradeItemId","quizGradeItemId","nextItemToFocus","nextElementSibling","quizgradeitems","deleteGradeItem","reRenderPage","resolve","document","querySelector","focus","catch","Notification","exception","stopEditingGadeItem","editableSpan","innerHTML","oldContent","classList","remove","handleGradeItemKeyDown","keyCode","newName","value","name","updateGradeItem","editGradingPageData","html","js","handleGradeItemKeyUp","handleGradeItemFocusOut","MoodleConfig","behatsiterunning","handleSlotGradeItemChanged","select","slotId","newGradeItemId","slots","quizgradeitemid","updateSlotGradeItem","handleGradeItemClick","link","actionDelete","actionEdit","querySelectorAll","forEach","instructions","uniqueId","editLabel","rawName","inputElement","add","handleGradeItemEditStart","handleButtonClick","handleAddGradeItemClick","handleAutoSetup","handleResetAllClick","parentNode","createGradeItem","autoSetupGradeItems","button","deleteCancelPromise","reallyResetAll","slotResets","map","length","tr","body","addEventListener"],"mappings":"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"}