Proyectos de Subversion Moodle

Rev

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

{"version":3,"file":"edittree_index.min.js","sources":["../src/edittree_index.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 * Enhance the gradebook tree setup with various facilities.\n *\n * @module     core_grades/edittree_index\n * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport storage from 'core/localstorage';\nimport {addIconToContainer} from 'core/loadingicon';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\n\nconst SELECTORS = {\n    CATEGORY_TOGGLE: '.toggle-category',\n    GRADEBOOK_SETUP_TABLE: '.setup-grades',\n    WEIGHT_OVERRIDE_CHECKBOX: '.weightoverride',\n    BULK_MOVE_SELECT: '#menumoveafter',\n    BULK_MOVE_INPUT: '#bulkmoveinput',\n    GRADEBOOK_SETUP_WRAPPER: '.gradetree-wrapper',\n    GRADEBOOK_SETUP_BOX: '.gradetreebox'\n};\n\n/**\n * Register related event listeners.\n *\n * @method registerListenerEvents\n * @param {int} courseId The ID of course.\n * @param {int} userId The ID of the current logged user.\n */\nconst registerListenerEvents = (courseId, userId) => {\n\n    document.addEventListener('change', e => {\n        // Toggle the availability of the weight input field based on the changed state (checked/unchecked) of the\n        // related checkbox element.\n        if (e.target.matches(SELECTORS.WEIGHT_OVERRIDE_CHECKBOX)) {\n            toggleWeightInput(e.target);\n        }\n        // Submit the bulk move form when the selected option in the bulk move select element has been changed.\n        if (e.target.matches(SELECTORS.BULK_MOVE_SELECT)) {\n            submitBulkMoveForm(e.target);\n        }\n    });\n\n    const gradebookSetup = document.querySelector(SELECTORS.GRADEBOOK_SETUP_TABLE);\n    gradebookSetup.addEventListener('click', e => {\n        const toggle = e.target.closest(SELECTORS.CATEGORY_TOGGLE);\n        // Collapse or expand the grade category when the visibility toggle button is activated.\n        if (toggle) {\n            e.preventDefault();\n            toggleCategory(toggle, courseId, userId, true);\n        }\n    });\n};\n\n/**\n * Toggle the weight input field based on its checkbox.\n *\n * @method toggleWeightInput\n * @param {object} weightOverrideCheckbox The weight override checkbox element.\n */\nconst toggleWeightInput = (weightOverrideCheckbox) => {\n    const row = weightOverrideCheckbox.closest('tr');\n    const itemId = row.dataset.itemid;\n    const weightOverrideInput = row.querySelector(`input[name=\"weight_${itemId}\"]`);\n    weightOverrideInput.disabled = !weightOverrideCheckbox.checked;\n};\n\n/**\n * Submit the bulk move form.\n *\n * @method toggleWeightInput\n * @param {object} bulkMoveSelect The bulk move select element.\n */\nconst submitBulkMoveForm = (bulkMoveSelect) => {\n    const form = bulkMoveSelect.closest('form');\n    const bulkMoveInput = form.querySelector(SELECTORS.BULK_MOVE_INPUT);\n    bulkMoveInput.value = 1;\n    form.submit();\n};\n\n/**\n * Method that collapses all relevant grade categories based on the locally stored state of collapsed grade categories\n * for a given user.\n *\n * @method collapseGradeCategories\n * @param {int} courseId The ID of course.\n * @param {int} userId The ID of the current logged user.\n */\nconst collapseGradeCategories = (courseId, userId) => {\n    const gradebookSetup = document.querySelector(SELECTORS.GRADEBOOK_SETUP_TABLE);\n    const storedCollapsedCategories = storage.get(`core_grade_collapsedgradecategories_${courseId}_${userId}`);\n\n    if (storedCollapsedCategories) {\n        // Fetch all grade categories that are locally stored as collapsed and re-apply the collapse action.\n        const collapsedCategories = JSON.parse(storedCollapsedCategories);\n\n        collapsedCategories.forEach((category) => {\n            const categoryToggleElement =\n                gradebookSetup.querySelector(`${SELECTORS.CATEGORY_TOGGLE}[data-category=\"${category}\"`);\n            if (categoryToggleElement) {\n                toggleCategory(categoryToggleElement, courseId, userId, false);\n            }\n        });\n    }\n};\n\n/**\n * Method that updates the locally stored state of collapsed grade categories based on a performed toggle action on a\n * given grade category.\n *\n * @method updateCollapsedCategoriesStoredState\n * @param {string} category The category to be added or removed from the collapsed grade categories local storage.\n * @param {int} courseId The ID of course.\n * @param {int} userId The ID of the current logged user.\n * @param {boolean} isCollapsing Whether the category is being collapsed or not.\n */\nconst updateCollapsedCategoriesStoredState = (category, courseId, userId, isCollapsing) => {\n    const currentStoredCollapsedCategories = storage.get(`core_grade_collapsedgradecategories_${courseId}_${userId}`);\n    let collapsedCategories = currentStoredCollapsedCategories ?\n        JSON.parse(currentStoredCollapsedCategories) : [];\n\n    if (isCollapsing) {\n        collapsedCategories.push(category);\n    } else {\n        collapsedCategories = collapsedCategories.filter(cat => cat !== category);\n    }\n    storage.set(`core_grade_collapsedgradecategories_${courseId}_${userId}`, JSON.stringify(collapsedCategories));\n};\n\n/**\n * Method that handles the grade category toggle action.\n *\n * @method toggleCategory\n * @param {object} toggleElement The category toggle node that was clicked.\n * @param {int} courseId The ID of course.\n * @param {int} userId The ID of the current logged user.\n * @param {boolean} storeCollapsedState Whether to store (local storage) the state of collapsed grade categories.\n */\nconst toggleCategory = (toggleElement, courseId, userId, storeCollapsedState) => {\n    const target = toggleElement.dataset.target;\n    const category = toggleElement.dataset.category;\n    // Whether the toggle action is collapsing the category or not.\n    const isCollapsing = toggleElement.getAttribute('aria-expanded') === \"true\";\n    const gradebookSetup = toggleElement.closest(SELECTORS.GRADEBOOK_SETUP_TABLE);\n    // Find all targeted 'children' rows of the toggled category.\n    const targetRows = gradebookSetup.querySelectorAll(target);\n    // Find the maximum grade cell in the grade category that is being collapsed/expanded.\n    const toggleElementRow = toggleElement.closest('tr');\n    const maxGradeCell = toggleElementRow.querySelector('.column-range');\n\n    if (isCollapsing) {\n        toggleElement.setAttribute('aria-expanded', 'false');\n        // Update the 'data-target' of the toggle category node to make sure that when we perform another toggle action\n        // to expand this category we only target rows which have been hidden by this category toggle action.\n        toggleElement.dataset.target = `[data-hidden-by='${category}']`;\n        if (maxGradeCell) {\n            const relatedCategoryAggregationRow = gradebookSetup.querySelector(`[data-aggregationforcategory='${category}']`);\n            maxGradeCell.innerHTML = relatedCategoryAggregationRow.querySelector('.column-range').innerHTML;\n        }\n    } else {\n        toggleElement.setAttribute('aria-expanded', 'true');\n        // Update the 'data-target' of the toggle category node to make sure that when we perform another toggle action\n        // to collapse this category we only target rows which are children of this category and are not currently hidden.\n        toggleElement.dataset.target = `.${category}[data-hidden='false']`;\n        if (maxGradeCell) {\n            maxGradeCell.innerHTML = '';\n        }\n    }\n    // If explicitly instructed, update accordingly the locally stored state of collapsed categories based on the\n    // toggle action performed on the given grade category.\n    if (storeCollapsedState) {\n        updateCollapsedCategoriesStoredState(category, courseId, userId, isCollapsing);\n    }\n\n    // Loop through all targeted child row elements and update the required data attributes to either hide or show\n    // them depending on the toggle action (collapsing or expanding).\n    targetRows.forEach((row) => {\n        if (isCollapsing) {\n            row.dataset.hidden = 'true';\n            row.dataset.hiddenBy = category;\n        } else {\n            row.dataset.hidden = 'false';\n            row.dataset.hiddenBy = '';\n        }\n    });\n\n    // Since the user report is presented in an HTML table, rowspans are used under each category to create a visual\n    // hierarchy between categories and grading items. When expanding or collapsing a category we need to also update\n    // (subtract or add) the rowspan values associated to each parent category row to preserve the correct visual\n    // hierarchy in the table.\n    updateParentCategoryRowspans(toggleElement, targetRows.length);\n};\n\n/**\n * Method that updates the rowspan value of all 'parent' category rows of a given category node.\n *\n * @method updateParentCategoryRowspans\n * @param {object} toggleElement The category toggle node that was clicked.\n * @param {int} num The number we want to add or subtract from the rowspan value of the 'parent' category row elements.\n */\nconst updateParentCategoryRowspans = (toggleElement, num) => {\n    const gradebookSetup = toggleElement.closest(SELECTORS.GRADEBOOK_SETUP_TABLE);\n    // Get the row element which contains the category toggle node.\n    const rowElement = toggleElement.closest('tr');\n\n    // Loop through the class list of the toggle category row element.\n    // The list contains classes which identify all parent categories of the toggled category.\n    rowElement.classList.forEach((className) => {\n        // Find the toggle node of the 'parent' category that is identified by the given class name.\n        const parentCategoryToggleElement = gradebookSetup.querySelector(`[data-target=\".${className}[data-hidden='false']\"`);\n        if (parentCategoryToggleElement) {\n            // Get the row element which contains the parent category toggle node.\n            const categoryRowElement = parentCategoryToggleElement.closest('tr');\n            // Find the rowspan element associated to this parent category.\n            const categoryRowSpanElement = categoryRowElement.nextElementSibling.querySelector('[rowspan]');\n\n            // Depending on whether the toggle action has expanded or collapsed the category, either add or\n            // subtract from the 'parent' category rowspan.\n            if (toggleElement.getAttribute('aria-expanded') === \"true\") {\n                categoryRowSpanElement.rowSpan = categoryRowSpanElement.rowSpan + num;\n            } else { // The category has been collapsed.\n                categoryRowSpanElement.rowSpan = categoryRowSpanElement.rowSpan - num;\n            }\n        }\n    });\n};\n\n/**\n * Initialize module.\n *\n * @method init\n * @param {int} courseId The ID of course.\n * @param {int} userId The ID of the current logged user.\n */\nexport const init = (courseId, userId) => {\n    const pendingPromise = new Pending();\n    const gradebookSetupBox = document.querySelector(SELECTORS.GRADEBOOK_SETUP_BOX);\n    // Display a loader while the relevant grade categories are being re-collapsed on page load (based on the locally\n    // stored state for the given user).\n    addIconToContainer(gradebookSetupBox).then((loader) => {\n        setTimeout(() => {\n            collapseGradeCategories(courseId, userId);\n            // Once the grade categories have been re-collapsed, remove the loader and display the Gradebook setup content.\n            loader.remove();\n            document.querySelector(SELECTORS.GRADEBOOK_SETUP_WRAPPER).classList.remove('d-none');\n            pendingPromise.resolve();\n        }, 150);\n        return;\n    }).fail(Notification.exception);\n\n    registerListenerEvents(courseId, userId);\n};\n"],"names":["SELECTORS","toggleWeightInput","weightOverrideCheckbox","row","closest","itemId","dataset","itemid","querySelector","disabled","checked","submitBulkMoveForm","bulkMoveSelect","form","value","submit","toggleCategory","toggleElement","courseId","userId","storeCollapsedState","target","category","isCollapsing","getAttribute","gradebookSetup","targetRows","querySelectorAll","maxGradeCell","setAttribute","relatedCategoryAggregationRow","innerHTML","currentStoredCollapsedCategories","storage","get","collapsedCategories","JSON","parse","push","filter","cat","set","stringify","updateCollapsedCategoriesStoredState","forEach","hidden","hiddenBy","updateParentCategoryRowspans","length","num","classList","className","parentCategoryToggleElement","categoryRowSpanElement","nextElementSibling","rowSpan","pendingPromise","Pending","gradebookSetupBox","document","then","loader","setTimeout","storedCollapsedCategories","categoryToggleElement","collapseGradeCategories","remove","resolve","fail","Notification","exception","addEventListener","e","matches","toggle","preventDefault","registerListenerEvents"],"mappings":"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"}