diff --git a/grade/amd/build/edittree_index.min.js b/grade/amd/build/edittree_index.min.js index 5325da74267..93869e0b88a 100644 --- a/grade/amd/build/edittree_index.min.js +++ b/grade/amd/build/edittree_index.min.js @@ -1,10 +1,10 @@ +define("core_grades/edittree_index",["exports","core/localstorage","core/loadingicon","core/notification","core/pending"],(function(_exports,_localstorage,_loadingicon,_notification,_pending){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} /** - * Enhance the gradebook tree setup with various facilities. - * - * @module core_grades/edittree_index - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -define("core_grades/edittree_index",["jquery"],(function($){var edittree=function(){$("body").on("change",".weightoverride",edittree.toggleWeightInput),$("#menumoveafter").on("change",(function(){var form=$(this).closest("form");form.find("#bulkmoveinput").val(1),form.submit()}))};return edittree.toggleWeightInput=function(e){e.preventDefault();var node=$(this),row=node.closest("tr");$('input[name="weight_'+row.data("itemid")+'"]').prop("disabled",!node.prop("checked"))},{enhance:edittree}})); + * Enhance the gradebook tree setup with various facilities. + * + * @module core_grades/edittree_index + * @copyright 2016 Andrew Nicols + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_localstorage=_interopRequireDefault(_localstorage),_notification=_interopRequireDefault(_notification),_pending=_interopRequireDefault(_pending);const SELECTORS_CATEGORY_TOGGLE=".toggle-category",SELECTORS_GRADEBOOK_SETUP_TABLE=".setup-grades",SELECTORS_WEIGHT_OVERRIDE_CHECKBOX=".weightoverride",SELECTORS_BULK_MOVE_SELECT="#menumoveafter",SELECTORS_BULK_MOVE_INPUT="#bulkmoveinput",SELECTORS_GRADEBOOK_SETUP_WRAPPER=".gradetree-wrapper",SELECTORS_GRADEBOOK_SETUP_BOX=".gradetreebox",toggleWeightInput=weightOverrideCheckbox=>{const row=weightOverrideCheckbox.closest("tr"),itemId=row.dataset.itemid;row.querySelector('input[name="weight_'.concat(itemId,'"]')).disabled=!weightOverrideCheckbox.checked},submitBulkMoveForm=bulkMoveSelect=>{const form=bulkMoveSelect.closest("form");form.querySelector(SELECTORS_BULK_MOVE_INPUT).value=1,form.submit()},toggleCategory=(toggleElement,courseId,userId,storeCollapsedState)=>{const target=toggleElement.dataset.target,category=toggleElement.dataset.category,isCollapsing="true"===toggleElement.getAttribute("aria-expanded"),gradebookSetup=toggleElement.closest(SELECTORS_GRADEBOOK_SETUP_TABLE),targetRows=gradebookSetup.querySelectorAll(target),maxGradeCell=toggleElement.closest("tr").querySelector(".column-range");if(isCollapsing){if(toggleElement.setAttribute("aria-expanded","false"),toggleElement.dataset.target="[data-hidden-by='".concat(category,"']"),maxGradeCell){const relatedCategoryAggregationRow=gradebookSetup.querySelector("[data-aggregationforcategory='".concat(category,"']"));maxGradeCell.innerHTML=relatedCategoryAggregationRow.querySelector(".column-range").innerHTML}}else toggleElement.setAttribute("aria-expanded","true"),toggleElement.dataset.target=".".concat(category,"[data-hidden='false']"),maxGradeCell&&(maxGradeCell.innerHTML="");storeCollapsedState&&((category,courseId,userId,isCollapsing)=>{const currentStoredCollapsedCategories=_localstorage.default.get("core_grade_collapsedgradecategories_".concat(courseId,"_").concat(userId));let collapsedCategories=currentStoredCollapsedCategories?JSON.parse(currentStoredCollapsedCategories):[];isCollapsing?collapsedCategories.push(category):collapsedCategories=collapsedCategories.filter((cat=>cat!==category)),_localstorage.default.set("core_grade_collapsedgradecategories_".concat(courseId,"_").concat(userId),JSON.stringify(collapsedCategories))})(category,courseId,userId,isCollapsing),targetRows.forEach((row=>{isCollapsing?(row.dataset.hidden="true",row.dataset.hiddenBy=category):(row.dataset.hidden="false",row.dataset.hiddenBy="")})),updateParentCategoryRowspans(toggleElement,targetRows.length)},updateParentCategoryRowspans=(toggleElement,num)=>{const gradebookSetup=toggleElement.closest(SELECTORS_GRADEBOOK_SETUP_TABLE);toggleElement.closest("tr").classList.forEach((className=>{const parentCategoryToggleElement=gradebookSetup.querySelector('[data-target=".'.concat(className,"[data-hidden='false']\""));if(parentCategoryToggleElement){const categoryRowSpanElement=parentCategoryToggleElement.closest("tr").nextElementSibling.querySelector("[rowspan]");"true"===toggleElement.getAttribute("aria-expanded")?categoryRowSpanElement.rowSpan=categoryRowSpanElement.rowSpan+num:categoryRowSpanElement.rowSpan=categoryRowSpanElement.rowSpan-num}}))};_exports.init=(courseId,userId)=>{const pendingPromise=new _pending.default,gradebookSetupBox=document.querySelector(SELECTORS_GRADEBOOK_SETUP_BOX);(0,_loadingicon.addIconToContainer)(gradebookSetupBox).then((loader=>{setTimeout((()=>{((courseId,userId)=>{const gradebookSetup=document.querySelector(SELECTORS_GRADEBOOK_SETUP_TABLE),storedCollapsedCategories=_localstorage.default.get("core_grade_collapsedgradecategories_".concat(courseId,"_").concat(userId));storedCollapsedCategories&&JSON.parse(storedCollapsedCategories).forEach((category=>{const categoryToggleElement=gradebookSetup.querySelector("".concat(SELECTORS_CATEGORY_TOGGLE,'[data-category="').concat(category,'"'));categoryToggleElement&&toggleCategory(categoryToggleElement,courseId,userId,!1)}))})(courseId,userId),loader.remove(),document.querySelector(SELECTORS_GRADEBOOK_SETUP_WRAPPER).classList.remove("d-none"),pendingPromise.resolve()}),150)})).fail(_notification.default.exception),((courseId,userId)=>{document.addEventListener("change",(e=>{e.target.matches(SELECTORS_WEIGHT_OVERRIDE_CHECKBOX)&&toggleWeightInput(e.target),e.target.matches(SELECTORS_BULK_MOVE_SELECT)&&submitBulkMoveForm(e.target)})),document.querySelector(SELECTORS_GRADEBOOK_SETUP_TABLE).addEventListener("click",(e=>{const toggle=e.target.closest(SELECTORS_CATEGORY_TOGGLE);toggle&&toggleCategory(toggle,courseId,userId,!0)}))})(courseId,userId)}})); //# sourceMappingURL=edittree_index.min.js.map \ No newline at end of file diff --git a/grade/amd/build/edittree_index.min.js.map b/grade/amd/build/edittree_index.min.js.map index 41f3a614a8a..a38559f4bcb 100644 --- a/grade/amd/build/edittree_index.min.js.map +++ b/grade/amd/build/edittree_index.min.js.map @@ -1 +1 @@ -{"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 .\n\n/**\n * Enhance the gradebook tree setup with various facilities.\n *\n * @module core_grades/edittree_index\n * @copyright 2016 Andrew Nicols \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n 'jquery',\n], function($) {\n /**\n * Enhance the edittree functionality.\n *\n * @method edittree\n */\n var edittree = function() {\n // Watch for the weight override checkboxes.\n $('body').on('change', '.weightoverride', edittree.toggleWeightInput);\n\n // Watch changes to the bulk move menu and submit.\n $('#menumoveafter').on('change', function() {\n var form = $(this).closest('form'),\n bulkmove = form.find('#bulkmoveinput');\n\n bulkmove.val(1);\n form.submit();\n });\n };\n\n /**\n * Toggle the weight input field based on its checkbox.\n *\n * @method toggleWeightInput\n * @param {EventFacade} e\n * @private\n */\n edittree.toggleWeightInput = function(e) {\n e.preventDefault();\n var node = $(this),\n row = node.closest('tr');\n\n $('input[name=\"weight_' + row.data('itemid') + '\"]').prop('disabled', !node.prop('checked'));\n };\n\n return /** @alias module:core_grades/edittree_index */ {\n enhance: edittree\n };\n});\n"],"names":["define","$","edittree","on","toggleWeightInput","form","this","closest","find","val","submit","e","preventDefault","node","row","data","prop","enhance"],"mappings":";;;;;;;AAsBAA,oCAAO,CACH,WACD,SAASC,OAMJC,SAAW,WAEXD,EAAE,QAAQE,GAAG,SAAU,kBAAmBD,SAASE,mBAGnDH,EAAE,kBAAkBE,GAAG,UAAU,eACzBE,KAAOJ,EAAEK,MAAMC,QAAQ,QACZF,KAAKG,KAAK,kBAEhBC,IAAI,GACbJ,KAAKK,oBAWbR,SAASE,kBAAoB,SAASO,GAClCA,EAAEC,qBACEC,KAAOZ,EAAEK,MACTQ,IAAMD,KAAKN,QAAQ,MAEvBN,EAAE,sBAAwBa,IAAIC,KAAK,UAAY,MAAMC,KAAK,YAAaH,KAAKG,KAAK,aAG9B,CACnDC,QAASf"} \ No newline at end of file +{"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 .\n\n/**\n * Enhance the gradebook tree setup with various facilities.\n *\n * @module core_grades/edittree_index\n * @copyright 2016 Andrew Nicols \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 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","registerListenerEvents"],"mappings":";;;;;;;0OA4BMA,0BACe,mBADfA,gCAEqB,gBAFrBA,mCAGwB,kBAHxBA,2BAIgB,iBAJhBA,0BAKe,iBALfA,kCAMuB,qBANvBA,8BAOmB,gBAwCnBC,kBAAqBC,+BACjBC,IAAMD,uBAAuBE,QAAQ,MACrCC,OAASF,IAAIG,QAAQC,OACCJ,IAAIK,2CAAoCH,cAChDI,UAAYP,uBAAuBQ,SASrDC,mBAAsBC,uBAClBC,KAAOD,eAAeR,QAAQ,QACdS,KAAKL,cAAcR,2BAC3Bc,MAAQ,EACtBD,KAAKE,UA6DHC,eAAiB,CAACC,cAAeC,SAAUC,OAAQC,6BAC/CC,OAASJ,cAAcX,QAAQe,OAC/BC,SAAWL,cAAcX,QAAQgB,SAEjCC,aAA+D,SAAhDN,cAAcO,aAAa,iBAC1CC,eAAiBR,cAAcb,QAAQJ,iCAEvC0B,WAAaD,eAAeE,iBAAiBN,QAG7CO,aADmBX,cAAcb,QAAQ,MACTI,cAAc,oBAEhDe,iBACAN,cAAcY,aAAa,gBAAiB,SAG5CZ,cAAcX,QAAQe,kCAA6BC,eAC/CM,aAAc,OACRE,8BAAgCL,eAAejB,sDAA+Cc,gBACpGM,aAAaG,UAAYD,8BAA8BtB,cAAc,iBAAiBuB,gBAG1Fd,cAAcY,aAAa,gBAAiB,QAG5CZ,cAAcX,QAAQe,kBAAaC,kCAC/BM,eACAA,aAAaG,UAAY,IAK7BX,qBAtDqC,EAACE,SAAUJ,SAAUC,OAAQI,sBAChES,iCAAmCC,sBAAQC,kDAA2ChB,qBAAYC,aACpGgB,oBAAsBH,iCACtBI,KAAKC,MAAML,kCAAoC,GAE/CT,aACAY,oBAAoBG,KAAKhB,UAEzBa,oBAAsBA,oBAAoBI,QAAOC,KAAOA,MAAQlB,iCAE5DmB,kDAA2CvB,qBAAYC,QAAUiB,KAAKM,UAAUP,uBA6CpFQ,CAAqCrB,SAAUJ,SAAUC,OAAQI,cAKrEG,WAAWkB,SAASzC,MACZoB,cACApB,IAAIG,QAAQuC,OAAS,OACrB1C,IAAIG,QAAQwC,SAAWxB,WAEvBnB,IAAIG,QAAQuC,OAAS,QACrB1C,IAAIG,QAAQwC,SAAW,OAQ/BC,6BAA6B9B,cAAeS,WAAWsB,SAUrDD,6BAA+B,CAAC9B,cAAegC,aAC3CxB,eAAiBR,cAAcb,QAAQJ,iCAE1BiB,cAAcb,QAAQ,MAI9B8C,UAAUN,SAASO,kBAEpBC,4BAA8B3B,eAAejB,uCAAgC2C,yCAC/EC,4BAA6B,OAIvBC,uBAFqBD,4BAA4BhD,QAAQ,MAEbkD,mBAAmB9C,cAAc,aAI/B,SAAhDS,cAAcO,aAAa,iBAC3B6B,uBAAuBE,QAAUF,uBAAuBE,QAAUN,IAElEI,uBAAuBE,QAAUF,uBAAuBE,QAAUN,uBAa9D,CAAC/B,SAAUC,gBACrBqC,eAAiB,IAAIC,iBACrBC,kBAAoBC,SAASnD,cAAcR,mEAG9B0D,mBAAmBE,MAAMC,SACxCC,YAAW,KAxJa,EAAC5C,SAAUC,gBACjCM,eAAiBkC,SAASnD,cAAcR,iCACxC+D,0BAA4B9B,sBAAQC,kDAA2ChB,qBAAYC,SAE7F4C,2BAE4B3B,KAAKC,MAAM0B,2BAEnBnB,SAAStB,iBACnB0C,sBACFvC,eAAejB,wBAAiBR,qDAA4CsB,eAC5E0C,uBACAhD,eAAegD,sBAAuB9C,SAAUC,QAAQ,OA6I5D8C,CAAwB/C,SAAUC,QAElC0C,OAAOK,SACPP,SAASnD,cAAcR,mCAAmCkD,UAAUgB,OAAO,UAC3EV,eAAeW,YAChB,QAEJC,KAAKC,sBAAaC,WA1NM,EAACpD,SAAUC,UAEtCwC,SAASY,iBAAiB,UAAUC,IAG5BA,EAAEnD,OAAOoD,QAAQzE,qCACjBC,kBAAkBuE,EAAEnD,QAGpBmD,EAAEnD,OAAOoD,QAAQzE,6BACjBW,mBAAmB6D,EAAEnD,WAINsC,SAASnD,cAAcR,iCAC/BuE,iBAAiB,SAASC,UAC/BE,OAASF,EAAEnD,OAAOjB,QAAQJ,2BAE5B0E,QACA1D,eAAe0D,OAAQxD,SAAUC,QAAQ,OAyMjDwD,CAAuBzD,SAAUC"} \ No newline at end of file diff --git a/grade/amd/src/edittree_index.js b/grade/amd/src/edittree_index.js index b0c513e2db9..16f1566e7b4 100644 --- a/grade/amd/src/edittree_index.js +++ b/grade/amd/src/edittree_index.js @@ -20,44 +20,248 @@ * @copyright 2016 Andrew Nicols * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define([ - 'jquery', -], function($) { - /** - * Enhance the edittree functionality. - * - * @method edittree - */ - var edittree = function() { - // Watch for the weight override checkboxes. - $('body').on('change', '.weightoverride', edittree.toggleWeightInput); - // Watch changes to the bulk move menu and submit. - $('#menumoveafter').on('change', function() { - var form = $(this).closest('form'), - bulkmove = form.find('#bulkmoveinput'); +import storage from 'core/localstorage'; +import {addIconToContainer} from 'core/loadingicon'; +import Notification from 'core/notification'; +import Pending from 'core/pending'; - bulkmove.val(1); - form.submit(); +const SELECTORS = { + CATEGORY_TOGGLE: '.toggle-category', + GRADEBOOK_SETUP_TABLE: '.setup-grades', + WEIGHT_OVERRIDE_CHECKBOX: '.weightoverride', + BULK_MOVE_SELECT: '#menumoveafter', + BULK_MOVE_INPUT: '#bulkmoveinput', + GRADEBOOK_SETUP_WRAPPER: '.gradetree-wrapper', + GRADEBOOK_SETUP_BOX: '.gradetreebox' +}; + +/** + * Register related event listeners. + * + * @method registerListenerEvents + * @param {int} courseId The ID of course. + * @param {int} userId The ID of the current logged user. + */ +const registerListenerEvents = (courseId, userId) => { + + document.addEventListener('change', e => { + // Toggle the availability of the weight input field based on the changed state (checked/unchecked) of the + // related checkbox element. + if (e.target.matches(SELECTORS.WEIGHT_OVERRIDE_CHECKBOX)) { + toggleWeightInput(e.target); + } + // Submit the bulk move form when the selected option in the bulk move select element has been changed. + if (e.target.matches(SELECTORS.BULK_MOVE_SELECT)) { + submitBulkMoveForm(e.target); + } + }); + + const gradebookSetup = document.querySelector(SELECTORS.GRADEBOOK_SETUP_TABLE); + gradebookSetup.addEventListener('click', e => { + const toggle = e.target.closest(SELECTORS.CATEGORY_TOGGLE); + // Collapse or expand the grade category when the visibility toggle button is activated. + if (toggle) { + toggleCategory(toggle, courseId, userId, true); + } + }); +}; + +/** + * Toggle the weight input field based on its checkbox. + * + * @method toggleWeightInput + * @param {object} weightOverrideCheckbox The weight override checkbox element. + */ +const toggleWeightInput = (weightOverrideCheckbox) => { + const row = weightOverrideCheckbox.closest('tr'); + const itemId = row.dataset.itemid; + const weightOverrideInput = row.querySelector(`input[name="weight_${itemId}"]`); + weightOverrideInput.disabled = !weightOverrideCheckbox.checked; +}; + +/** + * Submit the bulk move form. + * + * @method toggleWeightInput + * @param {object} bulkMoveSelect The bulk move select element. + */ +const submitBulkMoveForm = (bulkMoveSelect) => { + const form = bulkMoveSelect.closest('form'); + const bulkMoveInput = form.querySelector(SELECTORS.BULK_MOVE_INPUT); + bulkMoveInput.value = 1; + form.submit(); +}; + +/** + * Method that collapses all relevant grade categories based on the locally stored state of collapsed grade categories + * for a given user. + * + * @method collapseGradeCategories + * @param {int} courseId The ID of course. + * @param {int} userId The ID of the current logged user. + */ +const collapseGradeCategories = (courseId, userId) => { + const gradebookSetup = document.querySelector(SELECTORS.GRADEBOOK_SETUP_TABLE); + const storedCollapsedCategories = storage.get(`core_grade_collapsedgradecategories_${courseId}_${userId}`); + + if (storedCollapsedCategories) { + // Fetch all grade categories that are locally stored as collapsed and re-apply the collapse action. + const collapsedCategories = JSON.parse(storedCollapsedCategories); + + collapsedCategories.forEach((category) => { + const categoryToggleElement = + gradebookSetup.querySelector(`${SELECTORS.CATEGORY_TOGGLE}[data-category="${category}"`); + if (categoryToggleElement) { + toggleCategory(categoryToggleElement, courseId, userId, false); + } }); - }; + } +}; - /** - * Toggle the weight input field based on its checkbox. - * - * @method toggleWeightInput - * @param {EventFacade} e - * @private - */ - edittree.toggleWeightInput = function(e) { - e.preventDefault(); - var node = $(this), - row = node.closest('tr'); +/** + * Method that updates the locally stored state of collapsed grade categories based on a performed toggle action on a + * given grade category. + * + * @method updateCollapsedCategoriesStoredState + * @param {string} category The category to be added or removed from the collapsed grade categories local storage. + * @param {int} courseId The ID of course. + * @param {int} userId The ID of the current logged user. + * @param {boolean} isCollapsing Whether the category is being collapsed or not. + */ +const updateCollapsedCategoriesStoredState = (category, courseId, userId, isCollapsing) => { + const currentStoredCollapsedCategories = storage.get(`core_grade_collapsedgradecategories_${courseId}_${userId}`); + let collapsedCategories = currentStoredCollapsedCategories ? + JSON.parse(currentStoredCollapsedCategories) : []; - $('input[name="weight_' + row.data('itemid') + '"]').prop('disabled', !node.prop('checked')); - }; + if (isCollapsing) { + collapsedCategories.push(category); + } else { + collapsedCategories = collapsedCategories.filter(cat => cat !== category); + } + storage.set(`core_grade_collapsedgradecategories_${courseId}_${userId}`, JSON.stringify(collapsedCategories)); +}; - return /** @alias module:core_grades/edittree_index */ { - enhance: edittree - }; -}); +/** + * Method that handles the grade category toggle action. + * + * @method toggleCategory + * @param {object} toggleElement The category toggle node that was clicked. + * @param {int} courseId The ID of course. + * @param {int} userId The ID of the current logged user. + * @param {boolean} storeCollapsedState Whether to store (local storage) the state of collapsed grade categories. + */ +const toggleCategory = (toggleElement, courseId, userId, storeCollapsedState) => { + const target = toggleElement.dataset.target; + const category = toggleElement.dataset.category; + // Whether the toggle action is collapsing the category or not. + const isCollapsing = toggleElement.getAttribute('aria-expanded') === "true"; + const gradebookSetup = toggleElement.closest(SELECTORS.GRADEBOOK_SETUP_TABLE); + // Find all targeted 'children' rows of the toggled category. + const targetRows = gradebookSetup.querySelectorAll(target); + // Find the maximum grade cell in the grade category that is being collapsed/expanded. + const toggleElementRow = toggleElement.closest('tr'); + const maxGradeCell = toggleElementRow.querySelector('.column-range'); + + if (isCollapsing) { + toggleElement.setAttribute('aria-expanded', 'false'); + // Update the 'data-target' of the toggle category node to make sure that when we perform another toggle action + // to expand this category we only target rows which have been hidden by this category toggle action. + toggleElement.dataset.target = `[data-hidden-by='${category}']`; + if (maxGradeCell) { + const relatedCategoryAggregationRow = gradebookSetup.querySelector(`[data-aggregationforcategory='${category}']`); + maxGradeCell.innerHTML = relatedCategoryAggregationRow.querySelector('.column-range').innerHTML; + } + } else { + toggleElement.setAttribute('aria-expanded', 'true'); + // Update the 'data-target' of the toggle category node to make sure that when we perform another toggle action + // to collapse this category we only target rows which are children of this category and are not currently hidden. + toggleElement.dataset.target = `.${category}[data-hidden='false']`; + if (maxGradeCell) { + maxGradeCell.innerHTML = ''; + } + } + // If explicitly instructed, update accordingly the locally stored state of collapsed categories based on the + // toggle action performed on the given grade category. + if (storeCollapsedState) { + updateCollapsedCategoriesStoredState(category, courseId, userId, isCollapsing); + } + + // Loop through all targeted child row elements and update the required data attributes to either hide or show + // them depending on the toggle action (collapsing or expanding). + targetRows.forEach((row) => { + if (isCollapsing) { + row.dataset.hidden = 'true'; + row.dataset.hiddenBy = category; + } else { + row.dataset.hidden = 'false'; + row.dataset.hiddenBy = ''; + } + }); + + // Since the user report is presented in an HTML table, rowspans are used under each category to create a visual + // hierarchy between categories and grading items. When expanding or collapsing a category we need to also update + // (subtract or add) the rowspan values associated to each parent category row to preserve the correct visual + // hierarchy in the table. + updateParentCategoryRowspans(toggleElement, targetRows.length); +}; + +/** + * Method that updates the rowspan value of all 'parent' category rows of a given category node. + * + * @method updateParentCategoryRowspans + * @param {object} toggleElement The category toggle node that was clicked. + * @param {int} num The number we want to add or subtract from the rowspan value of the 'parent' category row elements. + */ +const updateParentCategoryRowspans = (toggleElement, num) => { + const gradebookSetup = toggleElement.closest(SELECTORS.GRADEBOOK_SETUP_TABLE); + // Get the row element which contains the category toggle node. + const rowElement = toggleElement.closest('tr'); + + // Loop through the class list of the toggle category row element. + // The list contains classes which identify all parent categories of the toggled category. + rowElement.classList.forEach((className) => { + // Find the toggle node of the 'parent' category that is identified by the given class name. + const parentCategoryToggleElement = gradebookSetup.querySelector(`[data-target=".${className}[data-hidden='false']"`); + if (parentCategoryToggleElement) { + // Get the row element which contains the parent category toggle node. + const categoryRowElement = parentCategoryToggleElement.closest('tr'); + // Find the rowspan element associated to this parent category. + const categoryRowSpanElement = categoryRowElement.nextElementSibling.querySelector('[rowspan]'); + + // Depending on whether the toggle action has expanded or collapsed the category, either add or + // subtract from the 'parent' category rowspan. + if (toggleElement.getAttribute('aria-expanded') === "true") { + categoryRowSpanElement.rowSpan = categoryRowSpanElement.rowSpan + num; + } else { // The category has been collapsed. + categoryRowSpanElement.rowSpan = categoryRowSpanElement.rowSpan - num; + } + } + }); +}; + +/** + * Initialize module. + * + * @method init + * @param {int} courseId The ID of course. + * @param {int} userId The ID of the current logged user. + */ +export const init = (courseId, userId) => { + const pendingPromise = new Pending(); + const gradebookSetupBox = document.querySelector(SELECTORS.GRADEBOOK_SETUP_BOX); + // Display a loader while the relevant grade categories are being re-collapsed on page load (based on the locally + // stored state for the given user). + addIconToContainer(gradebookSetupBox).then((loader) => { + setTimeout(() => { + collapseGradeCategories(courseId, userId); + // Once the grade categories have been re-collapsed, remove the loader and display the Gradebook setup content. + loader.remove(); + document.querySelector(SELECTORS.GRADEBOOK_SETUP_WRAPPER).classList.remove('d-none'); + pendingPromise.resolve(); + }, 150); + return; + }).fail(Notification.exception); + + registerListenerEvents(courseId, userId); +}; diff --git a/grade/edit/tree/index.php b/grade/edit/tree/index.php index c84b9700ec8..a795705c821 100644 --- a/grade/edit/tree/index.php +++ b/grade/edit/tree/index.php @@ -47,7 +47,7 @@ require_login($course); $context = context_course::instance($course->id); require_capability('moodle/grade:manage', $context); -$PAGE->requires->js_call_amd('core_grades/edittree_index', 'enhance'); +$PAGE->requires->js_call_amd('core_grades/edittree_index', 'init', [$courseid, $USER->id]); /// return tracking object $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid)); @@ -279,19 +279,15 @@ if ($weightsadjusted) { $tpldata->table = html_writer::table($grade_edit_tree->table); +if ($moving) { + $tpldata->cancelmovingbutton = $OUTPUT->single_button( + new moodle_url('index.php', ['id' => $course->id]), get_string('cancel'), 'get'); +} + echo $OUTPUT->render_from_template('core_grades/edit_tree', $tpldata); echo $OUTPUT->box_end(); -// Print action buttons -echo $OUTPUT->container_start('buttons mdl-align'); - -if ($moving) { - echo $OUTPUT->single_button(new moodle_url('index.php', array('id'=>$course->id)), get_string('cancel'), 'get'); -} - -echo $OUTPUT->container_end(); - $PAGE->requires->js_call_amd('core_form/changechecker', 'watchFormById', ['gradetreeform']); echo $OUTPUT->footer(); diff --git a/grade/edit/tree/lib.php b/grade/edit/tree/lib.php index f40be67fd93..7e9bce6b6a9 100644 --- a/grade/edit/tree/lib.php +++ b/grade/edit/tree/lib.php @@ -192,7 +192,19 @@ class grade_edit_tree { $cell->attributes['class'] = $element['type'] . ' moving column-name level' . ($level + 1) . ' level' . ($level % 2 ? 'even' : 'odd'); $cell->text = $object->name.' ('.get_string('move').')'; - return array(new html_table_row(array($cell))); + + // Create a row that represents the available area to move a grade item or a category into. + $movingarea = new html_table_row(); + // Obtain all parent category identifiers for this item and add them to its class list. This information + // will be used when collapsing or expanding grade categories to properly show or hide this area. + $parentcategories = array_merge($rowclasses, [$eid]); + $movingarea->attributes = [ + 'class' => implode(' ', $parentcategories), + 'data-hidden' => 'false' + ]; + $movingarea->cells[] = $cell; + + return [$movingarea]; } if ($element['type'] == 'category') { @@ -249,7 +261,14 @@ class grade_edit_tree { $cell->text = html_writer::link($aurl, html_writer::empty_tag('hr'), ['title' => get_string('movehere'), 'class' => 'movehere']); - $moveto = new html_table_row(array($cell)); + // Create a row that represents the available area to move a grade item or a category into. + $moveto = new html_table_row(); + // Obtain all parent category identifiers for this item and add them to its class list. This information + // will be used when collapsing or expanding grade categories to properly show or hide this area. + $parentcategories = array_merge($rowclasses, [$eid]); + $moveto->attributes['class'] = implode(' ', $parentcategories); + $moveto->attributes['data-hidden'] = 'false'; + $moveto->cells[] = $cell; } $newparents = $parents; @@ -308,6 +327,7 @@ class grade_edit_tree { $categoryrow->attributes['class'] = $courseclass . ' category ' . $dimmed; $categoryrow->attributes['data-category'] = $eid; $categoryrow->attributes['data-itemid'] = $category->get_grade_item()->id; + $categoryrow->attributes['data-hidden'] = 'false'; foreach ($rowclasses as $class) { $categoryrow->attributes['class'] .= ' ' . $class; } @@ -326,7 +346,11 @@ class grade_edit_tree { } $emptyrow = new html_table_row(); - $emptyrow->attributes['class'] = 'spacer'; + // Obtain all parent category identifiers for this item and add them to its class list. This information + // will be used when collapsing or expanding grade categories to properly show or hide this area. + $parentcategories = array_merge($rowclasses, [$eid]); + $emptyrow->attributes['class'] = 'spacer ' . implode(' ', $parentcategories); + $emptyrow->attributes['data-hidden'] = 'false'; $headercell = new html_table_cell(); $headercell->header = true; @@ -363,6 +387,14 @@ class grade_edit_tree { $gradeitemrow->id = 'grade-item-' . $eid; $gradeitemrow->attributes['class'] = $categoryitemclass . ' item ' . $dimmed; $gradeitemrow->attributes['data-itemid'] = $object->id; + $gradeitemrow->attributes['data-hidden'] = 'false'; + // If this item is a course or category aggregation, add a data attribute that stores the identifier of + // the related category or course. This attribute is used when collapsing a grade category to fetch the + // max grade from the aggregation and display it in the grade category row when the category items are + // collapsed and the aggregated max grade is not visible. + if (!empty($categoryitemclass)) { + $gradeitemrow->attributes['data-aggregationforcategory'] = $parent_eid; + } foreach ($rowclasses as $class) { $gradeitemrow->attributes['class'] .= ' ' . $class; } @@ -829,13 +861,19 @@ class grade_edit_tree_column_name extends grade_edit_tree_column { } public function get_category_cell($category, $levelclass, $params) { + global $OUTPUT; + if (empty($params['name']) || empty($params['level'])) { throw new Exception('Array key (name or level) missing from 3rd param of grade_edit_tree_column_name::get_category_cell($category, $levelclass, $params)'); } + $visibilitytoggle = $OUTPUT->render_from_template('core_grades/grade_category_visibility_toggle', [ + 'category' => $params['eid'] + ]); + $moveaction = isset($params['moveaction']) ? $params['moveaction'] : ''; $categorycell = parent::get_category_cell($category, $levelclass, $params); $categorycell->colspan = ($this->deepest_level + 2) - $params['level']; - $categorycell->text = html_writer::div($moveaction . $params['name'], 'font-weight-bold'); + $categorycell->text = html_writer::div($visibilitytoggle . $moveaction . $params['name'], 'font-weight-bold'); return $categorycell; } @@ -927,7 +965,7 @@ class grade_edit_tree_column_range extends grade_edit_tree_column { public function get_category_cell($category, $levelclass, $params) { $categorycell = parent::get_category_cell($category, $levelclass, $params); - $categorycell->text = ' - '; + $categorycell->text = ''; return $categorycell; } diff --git a/grade/templates/edit_tree.mustache b/grade/templates/edit_tree.mustache index e9317ce42de..86ad03a376c 100644 --- a/grade/templates/edit_tree.mustache +++ b/grade/templates/edit_tree.mustache @@ -27,6 +27,7 @@ * showbulkmove - boolean - Whether to show the bulk move select menu. * table - string - HTML content of the grade items table. * bulkmoveoptions - array - Key-value pair array for the options of the the bulk move select menu element. + * cancelmovingbutton - HTML content of the cancel move button. Example context (json): { @@ -38,33 +39,36 @@ "showbulkmove": "true", "bulkmoveoptions": "{'value' : '1', 'name' : 'Test grade category'}", "value": "1", - "name": "Test grade category" + "name": "Test grade category", + "cancelmovingbutton": "
" } }} - -
-
- - {{#notification}} - {{>core/notification_info}} - {{/notification}} - {{{table}}} -
- {{#showsave}} - - {{/showsave}} - {{#showbulkmove}} -
- - - -
- {{/showbulkmove}} +{{#notification}} + {{>core/notification_info}} +{{/notification}} +
+ +
+ + {{{table}}} +
+ {{#showsave}} + + {{/showsave}} + {{#showbulkmove}} +
+ + + +
+ {{/showbulkmove}} +
-
- + + {{{cancelmovingbutton}}} +
diff --git a/grade/templates/grade_category_visibility_toggle.mustache b/grade/templates/grade_category_visibility_toggle.mustache new file mode 100644 index 00000000000..03ca72834d4 --- /dev/null +++ b/grade/templates/grade_category_visibility_toggle.mustache @@ -0,0 +1,34 @@ +{{! + This file is part of Moodle - http://moodle.org/ + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template core_grades/grade_category_visibility_toggle + + Template for the grade category visibility toggle element. + + Context variables required for this template: + * category - The grade category identifier + + Example context (json): + { + "category": "gc2" + } +}} + + + + + + diff --git a/grade/tests/behat/toggle_grade_categories.feature b/grade/tests/behat/toggle_grade_categories.feature new file mode 100644 index 00000000000..64a26841816 --- /dev/null +++ b/grade/tests/behat/toggle_grade_categories.feature @@ -0,0 +1,281 @@ +@core @core_grades @javascript +Feature: Teachers can toggle the visibility of the grade categories in the Gradebook setup page. + In order to focus only on the information that I am interested in + As a teacher + I need to be able to easily toggle the visibility of grade categories in the Gradebook setup page + + Background: + Given the following "courses" exist: + | fullname | shortname | category | + | Course | C1 | 0 | + And the following "users" exist: + | username | firstname | lastname | email | idnumber | + | teacher1 | Teacher 1 | 1 | teacher1@example.com | t1 | + | teacher2 | Teacher 2 | 2 | teacher2@example.com | t2 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | teacher2 | C1 | editingteacher | + And the following "grade categories" exist: + | fullname | course | + | Category 1 | C1 | + And the following "activities" exist: + | activity | course | idnumber | name | intro | + | assign | C1 | a1 | Test assignment one | Submit something! | + And the following "activities" exist: + | activity | course | idnumber | name | intro | gradecategory | + | assign | C1 | a2 | Test assignment two | Submit something! | Category 1 | + And the following "grade items" exist: + | itemname | grademax | course | gradecategory | + | Manual grade | 40 | C1 | Category 1 | + And I log in as "teacher1" + And I am on "Course" course homepage + + Scenario: A teacher can collapse and expand grade categories in the Gradebook setup page + Given I navigate to "Setup > Gradebook setup" in the course gradebook + And the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Test assignment two | + | Manual grade | + | Category 1 total | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Collapse" "link" should exist in the "Category 1" "table_row" + # Collapse the grade category 'Category 1'. + When I click on "Collapse" "link" in the "Category 1" "table_row" + Then the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Expand" "link" should exist in the "Category 1" "table_row" + And the following should not exist in the "user-grades" table: + | Test assignment two | + | Manual grade | + | Category 1 total | + # Expand the grade category 'Category 1'. + And I click on "Expand" "link" in the "Category 1" "table_row" + And the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Test assignment two | + | Manual grade | + | Category 1 total | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Collapse" "link" should exist in the "Category 1" "table_row" + # Collapse again the grade category 'Category 1'. + And I click on "Collapse" "link" in the "Category 1" "table_row" + # Collapse the grade category 'Course'. + And I click on "Collapse" "link" in the "Course" "table_row" + And the following should exist in the "setup-grades" table: + | Name | + | Course | + And I should see "Course" in the "setup-grades" "table" + And "Expand" "link" should exist in the "Course" "table_row" + And the following should not exist in the "setup-grades" table: + | Name | + | Test assignment one | + | Category 1 | + | Test assignment two | + | Manual grade | + | Category 1 total | + | Course total | + # Expand the grade category 'Course'. 'Category 1' should be still collapsed. + And I click on "Expand" "link" in the "Course" "table_row" + And the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Expand" "link" should exist in the "Category 1" "table_row" + And the following should not exist in the "setup-grades" table: + | Name | + | Test assignment two | + | Manual grade | + | Category 1 total | + + Scenario: A teacher can see the aggregated max grade for a grade category even when the category is collapsed + Given I navigate to "Setup > Gradebook setup" in the course gradebook + And the following should exist in the "setup-grades" table: + | Name | Max grade | + | Course | | + | Category 1 | | + | Category 1 total | 140.00 | + | Course total | 240.00 | + # Collapse the grade category 'Category 1'. The aggregated max grade should now be displayed within the 'Category 1' row. + When I click on "Collapse" "link" in the "Category 1" "table_row" + Then the following should exist in the "setup-grades" table: + | Name | Max grade | + | Course | | + | Category 1 | 140.00 | + | Course total | 240.00 | + And I should not see "Category 1 total" in the "setup-grades" "table" + # Collapse the grade category 'Course'. The aggregated max grade should now be displayed within the 'Course' row. + And I click on "Collapse" "link" in the "Course" "table_row" + And "Course" row "Max grade" column of "setup-grades" table should contain "240.00" + And I should not see "Course total" in the "setup-grades" "table" + # Expand the grade category 'Course'. The aggregated max grade should not be displayed within the 'Course' row anymore. + And I click on "Expand" "link" in the "Course" "table_row" + | Name | Max grade | + | Course | | + | Category 1 | 140.00 | + | Course total | 240.00 | + + Scenario: A teacher can collapse and expand grade categories in the Gradebook setup when moving grade items + Given I navigate to "Setup > Gradebook setup" in the course gradebook + And I click on "Move" "link" in the "Test assignment one" "table_row" + And the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Test assignment two | + | Manual grade | + | Category 1 total | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Collapse" "link" should exist in the "Category 1" "table_row" + # Collapse the grade category 'Category 1'. + When I click on "Collapse" "link" in the "Category 1" "table_row" + Then the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Expand" "link" should exist in the "Category 1" "table_row" + And the following should not exist in the "setup-grades" table: + | Name | + | Test assignment two | + | Manual grade | + | Category 1 total | + # Expand the grade category 'Category 1'. + And I click on "Expand" "link" in the "Category 1" "table_row" + And the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Test assignment two | + | Manual grade | + | Category 1 total | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Collapse" "link" should exist in the "Category 1" "table_row" + # Collapse again the grade category 'Category 1'. + And I click on "Collapse" "link" in the "Category 1" "table_row" + # Collapse the grade category 'Course'. + And I click on "Collapse" "link" in the "Course" "table_row" + And I should see "Course" in the "setup-grades" "table" + And "Expand" "link" should exist in the "Course" "table_row" + And the following should not exist in the "setup-grades" table: + | Name | + | Test assignment one | + | Category 1 | + | Test assignment two | + | Manual grade | + | Category 1 total | + | Course total | + # Expand the grade category 'Course'. 'Category 1' should be still collapsed. + And I click on "Expand" "link" in the "Course" "table_row" + And the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Expand" "link" should exist in the "Category 1" "table_row" + And the following should not exist in the "setup-grades" table: + | Name | + | Test assignment two | + | Manual grade | + | Category 1 total | + + Scenario: Previously collapsed categories are still shown as collapsed when a teacher navigates back to Gradebook setup + Given I navigate to "Setup > Gradebook setup" in the course gradebook + # Collapse the grade category 'Category 1' and navigate to the course homepage. + And I click on "Collapse" "link" in the "Category 1" "table_row" + And I am on "Course" course homepage + # Navigate back to Gradebook setup and confirm that the category 'Category 1' is still collapsed. + When I navigate to "Setup > Gradebook setup" in the course gradebook + Then the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Expand" "link" should exist in the "Category 1" "table_row" + And the following should not exist in the "setup-grades" table: + | Name | + | Test assignment two | + | Manual grade | + | Category 1 total | + + Scenario: Previously collapsed categories are still shown as collapsed when a teacher is moving grade items in Gradebook setup + Given I navigate to "Setup > Gradebook setup" in the course gradebook + # Collapse the grade category 'Category 1'. + And I click on "Collapse" "link" in the "Category 1" "table_row" + # Attempt to move a grade item and confirm that the category 'Category 1' is still collapsed. + When I click on "Move" "link" in the "Test assignment one" "table_row" + Then the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Expand" "link" should exist in the "Category 1" "table_row" + And the following should not exist in the "setup-grades" table: + | Name | + | Test assignment two | + | Manual grade | + | Category 1 total | + + Scenario: Grade categories are shown as collapsed only to the teacher that collapsed them + Given I navigate to "Setup > Gradebook setup" in the course gradebook + # Collapse the grade category 'Category 1'. + And I click on "Collapse" "link" in the "Category 1" "table_row" + # Log in as teacher2 and confirm that the category 'Category 1' is not collapsed. + And I log in as "teacher2" + And I am on "Course" course homepage + When I navigate to "Setup > Gradebook setup" in the course gradebook + Then the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Test assignment two | + | Manual grade | + | Category 1 total | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Collapse" "link" should exist in the "Category 1" "table_row" + # Log in as teacher1 and confirm that the category 'Category 1' is still collapsed. + And I log in as "teacher1" + And I am on "Course" course homepage + And I navigate to "Setup > Gradebook setup" in the course gradebook + And the following should exist in the "setup-grades" table: + | Name | + | Course | + | Test assignment one | + | Category 1 | + | Course total | + And "Collapse" "link" should exist in the "Course" "table_row" + And "Expand" "link" should exist in the "Category 1" "table_row" + And the following should not exist in the "setup-grades" table: + | Name | + | Test assignment two | + | Manual grade | + | Category 1 total | diff --git a/theme/boost/scss/moodle/grade.scss b/theme/boost/scss/moodle/grade.scss index 1aba411919a..8614f25fb5c 100644 --- a/theme/boost/scss/moodle/grade.scss +++ b/theme/boost/scss/moodle/grade.scss @@ -2,8 +2,6 @@ // "Gradebook setup" > "Simple view" and "Full view". .gradetreebox { margin: 20px 0 30px 0; - padding: 10px 10px; - background-color: $gray-100; h4 { // Force back the base font-size to minimise width. @@ -300,137 +298,56 @@ } // Set up grades layout. -.path-grade-edit-tree .setup-grades { - h4 { - margin: 0; - } +.path-grade-edit-tree { + .gradetree-wrapper { + padding: 10px 10px; + background-color: $gray-100; - .column-rowspan { - padding: 0; - width: 24px; - min-width: 24px; - max-width: 24px; - } - - .emptyrow { - display: none; - } - - .gradeitemdescription { - font-weight: normal; - padding-left: 24px; - } - - &.generaltable { - - tr { - &.spacer { - height: 0.5rem; + .setup-grades { + h4 { + margin: 0; } - th { - vertical-align: bottom; - border: none; - text-align: left; - background-color: $gray-100; - - &.rowspan { - padding: 0; - width: 24px; - min-width: 24px; - } + .column-rowspan { + padding: 0; + width: 24px; + min-width: 24px; + max-width: 24px; } - td { - min-width: 4.5em; - background-color: $gray-100; - border: none; - vertical-align: middle; + .emptyrow { + display: none; + } - &.column-name { - padding-left: 24px; + .gradeitemdescription { + font-weight: normal; + padding-left: 24px; + } - .small { - font-size: 70%; + &.generaltable { + + tr { + &.spacer { + height: 0.5rem; } - .itemicon { - font-size: 18px; - width: 18px; - height: 18px; - } - } - - &.column-weight { - .weightoverride { - margin-right: 5px; - } - } - - &.column-actions { - .dropdown-toggle::after { + &[data-hidden="true"] { display: none; } - } - &.movehere { - padding: 0; - - a.movehere { - display: block; - width: 100%; - margin: 5px 0 5px 0; - padding: 3px 0 3px 0; - - hr { - border-top: 2px dashed $gray-500; - margin: 0; - } - - &:hover { - hr { - border-top: 2px dashed $blue; - } + th { + vertical-align: bottom; + border: none; + text-align: left; + background-color: $gray-100; + &.rowspan { + padding: 0; + width: 24px; + min-width: 24px; } } - } - } - &.category { - td { - background-color: white; - border-top: 1px solid $gray-300; - border-bottom: 1px solid $gray-300; - - &:first-child { - border-left: 1px solid $gray-300; - } - - &:last-child { - border-right: 1px solid $gray-300; - } - - &.column-name { - font-weight: bold; - - div { - display: flex; - min-height: 30px; - align-items: center; - } - } - } - } - - &.item { - td { - background-color: white; - border-top: 3px solid $gray-100; - } - - &.categoryitem, - &.courseitem { td { min-width: 4.5em; background-color: $gray-100; @@ -438,11 +355,127 @@ vertical-align: middle; &.column-name { - padding-left: 0; + padding-left: 38px; + + .small { + font-size: 70%; + } + + .itemicon { + font-size: 18px; + width: 18px; + height: 18px; + } } - &:not(.column-actions) { - font-weight: bold; + &.column-weight { + .weightoverride { + margin-right: 5px; + } + } + + &.column-actions { + .dropdown-toggle::after { + display: none; + } + } + + &.movehere { + padding: 0; + + a.movehere { + display: block; + width: 100%; + margin: 5px 0 5px 0; + padding: 3px 0 3px 0; + + hr { + border-top: 2px dashed $gray-500; + margin: 0; + } + + &:hover { + hr { + border-top: 2px dashed $blue; + } + + } + } + } + } + + &.category { + td { + background-color: white; + border-top: 1px solid $gray-300; + border-bottom: 1px solid $gray-300; + + &:first-child { + border-left: 1px solid $gray-300; + } + + &:last-child { + border-right: 1px solid $gray-300; + } + + &.column-name { + padding-left: 10px; + font-weight: bold; + + div { + display: flex; + min-height: 30px; + align-items: center; + + a { + &.toggle-category { + height: 24px; + width: 24px; + font-size: 12px; + line-height: 24px; + margin-right: 3px; + + &[aria-expanded="true"] .expanded, + &[aria-expanded="false"] .collapsed { + display: none; + } + + i { + font-size: 12px; + width: 12px; + height: 12px; + color: #1d2125; + margin: 0; + } + } + } + } + } + } + } + + &.item { + td { + background-color: white; + border-top: 3px solid $gray-100; + } + + &.categoryitem, + &.courseitem { + td { + min-width: 4.5em; + background-color: $gray-100; + border: none; + vertical-align: middle; + + &.column-name { + padding-left: 0; + } + + &:not(.column-actions) { + font-weight: bold; + } + } } } } diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index e7d782aa5bd..f1d7b403193 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -34589,8 +34589,6 @@ p.arrow_button { .gradetreebox { margin: 20px 0 30px 0; - padding: 10px 10px; - background-color: #f8f9fa; } .gradetreebox h4 { font-size: 0.9375rem; @@ -34811,108 +34809,133 @@ p.arrow_button { display: block; } -.path-grade-edit-tree .setup-grades h4 { +.path-grade-edit-tree .gradetree-wrapper { + padding: 10px 10px; + background-color: #f8f9fa; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades h4 { margin: 0; } -.path-grade-edit-tree .setup-grades .column-rowspan { +.path-grade-edit-tree .gradetree-wrapper .setup-grades .column-rowspan { padding: 0; width: 24px; min-width: 24px; max-width: 24px; } -.path-grade-edit-tree .setup-grades .emptyrow { +.path-grade-edit-tree .gradetree-wrapper .setup-grades .emptyrow { display: none; } -.path-grade-edit-tree .setup-grades .gradeitemdescription { +.path-grade-edit-tree .gradetree-wrapper .setup-grades .gradeitemdescription { font-weight: normal; padding-left: 24px; } -.path-grade-edit-tree .setup-grades.generaltable tr.spacer { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.spacer { height: 0.5rem; } -.path-grade-edit-tree .setup-grades.generaltable tr th { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr[data-hidden=true] { + display: none; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr th { vertical-align: bottom; border: none; text-align: left; background-color: #f8f9fa; } -.path-grade-edit-tree .setup-grades.generaltable tr th.rowspan { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr th.rowspan { padding: 0; width: 24px; min-width: 24px; } -.path-grade-edit-tree .setup-grades.generaltable tr td { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td { min-width: 4.5em; background-color: #f8f9fa; border: none; vertical-align: middle; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-name { - padding-left: 24px; +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-name { + padding-left: 38px; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-name .small { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-name .small { font-size: 70%; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-name .itemicon { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-name .itemicon { font-size: 18px; width: 18px; height: 18px; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-weight .weightoverride { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-weight .weightoverride { margin-right: 5px; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-actions .dropdown-toggle::after { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-actions .dropdown-toggle::after { display: none; } -.path-grade-edit-tree .setup-grades.generaltable tr td.movehere { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.movehere { padding: 0; } -.path-grade-edit-tree .setup-grades.generaltable tr td.movehere a.movehere { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.movehere a.movehere { display: block; width: 100%; margin: 5px 0 5px 0; padding: 3px 0 3px 0; } -.path-grade-edit-tree .setup-grades.generaltable tr td.movehere a.movehere hr { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.movehere a.movehere hr { border-top: 2px dashed #8f959e; margin: 0; } -.path-grade-edit-tree .setup-grades.generaltable tr td.movehere a.movehere:hover hr { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.movehere a.movehere:hover hr { border-top: 2px dashed #0f6cbf; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td { background-color: white; border-top: 1px solid #dee2e6; border-bottom: 1px solid #dee2e6; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td:first-child { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td:first-child { border-left: 1px solid #dee2e6; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td:last-child { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td:last-child { border-right: 1px solid #dee2e6; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td.column-name { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name { + padding-left: 10px; font-weight: bold; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td.column-name div { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div { display: flex; min-height: 30px; align-items: center; } -.path-grade-edit-tree .setup-grades.generaltable tr.item td { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div a.toggle-category { + height: 24px; + width: 24px; + font-size: 12px; + line-height: 24px; + margin-right: 3px; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div a.toggle-category[aria-expanded=true] .expanded, .path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div a.toggle-category[aria-expanded=false] .collapsed { + display: none; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div a.toggle-category i { + font-size: 12px; + width: 12px; + height: 12px; + color: #1d2125; + margin: 0; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item td { background-color: white; border-top: 3px solid #f8f9fa; } -.path-grade-edit-tree .setup-grades.generaltable tr.item.categoryitem td, .path-grade-edit-tree .setup-grades.generaltable tr.item.courseitem td { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.categoryitem td, .path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.courseitem td { min-width: 4.5em; background-color: #f8f9fa; border: none; vertical-align: middle; } -.path-grade-edit-tree .setup-grades.generaltable tr.item.categoryitem td.column-name, .path-grade-edit-tree .setup-grades.generaltable tr.item.courseitem td.column-name { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.categoryitem td.column-name, .path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.courseitem td.column-name { padding-left: 0; } -.path-grade-edit-tree .setup-grades.generaltable tr.item.categoryitem td:not(.column-actions), .path-grade-edit-tree .setup-grades.generaltable tr.item.courseitem td:not(.column-actions) { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.categoryitem td:not(.column-actions), .path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.courseitem td:not(.column-actions) { font-weight: bold; } diff --git a/theme/classic/style/moodle.css b/theme/classic/style/moodle.css index 399edec5c33..5e96ab8db4a 100644 --- a/theme/classic/style/moodle.css +++ b/theme/classic/style/moodle.css @@ -34589,8 +34589,6 @@ p.arrow_button { .gradetreebox { margin: 20px 0 30px 0; - padding: 10px 10px; - background-color: #f8f9fa; } .gradetreebox h4 { font-size: 0.9375rem; @@ -34811,108 +34809,133 @@ p.arrow_button { display: block; } -.path-grade-edit-tree .setup-grades h4 { +.path-grade-edit-tree .gradetree-wrapper { + padding: 10px 10px; + background-color: #f8f9fa; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades h4 { margin: 0; } -.path-grade-edit-tree .setup-grades .column-rowspan { +.path-grade-edit-tree .gradetree-wrapper .setup-grades .column-rowspan { padding: 0; width: 24px; min-width: 24px; max-width: 24px; } -.path-grade-edit-tree .setup-grades .emptyrow { +.path-grade-edit-tree .gradetree-wrapper .setup-grades .emptyrow { display: none; } -.path-grade-edit-tree .setup-grades .gradeitemdescription { +.path-grade-edit-tree .gradetree-wrapper .setup-grades .gradeitemdescription { font-weight: normal; padding-left: 24px; } -.path-grade-edit-tree .setup-grades.generaltable tr.spacer { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.spacer { height: 0.5rem; } -.path-grade-edit-tree .setup-grades.generaltable tr th { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr[data-hidden=true] { + display: none; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr th { vertical-align: bottom; border: none; text-align: left; background-color: #f8f9fa; } -.path-grade-edit-tree .setup-grades.generaltable tr th.rowspan { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr th.rowspan { padding: 0; width: 24px; min-width: 24px; } -.path-grade-edit-tree .setup-grades.generaltable tr td { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td { min-width: 4.5em; background-color: #f8f9fa; border: none; vertical-align: middle; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-name { - padding-left: 24px; +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-name { + padding-left: 38px; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-name .small { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-name .small { font-size: 70%; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-name .itemicon { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-name .itemicon { font-size: 18px; width: 18px; height: 18px; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-weight .weightoverride { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-weight .weightoverride { margin-right: 5px; } -.path-grade-edit-tree .setup-grades.generaltable tr td.column-actions .dropdown-toggle::after { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.column-actions .dropdown-toggle::after { display: none; } -.path-grade-edit-tree .setup-grades.generaltable tr td.movehere { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.movehere { padding: 0; } -.path-grade-edit-tree .setup-grades.generaltable tr td.movehere a.movehere { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.movehere a.movehere { display: block; width: 100%; margin: 5px 0 5px 0; padding: 3px 0 3px 0; } -.path-grade-edit-tree .setup-grades.generaltable tr td.movehere a.movehere hr { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.movehere a.movehere hr { border-top: 2px dashed #8f959e; margin: 0; } -.path-grade-edit-tree .setup-grades.generaltable tr td.movehere a.movehere:hover hr { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr td.movehere a.movehere:hover hr { border-top: 2px dashed #0f6cbf; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td { background-color: white; border-top: 1px solid #dee2e6; border-bottom: 1px solid #dee2e6; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td:first-child { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td:first-child { border-left: 1px solid #dee2e6; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td:last-child { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td:last-child { border-right: 1px solid #dee2e6; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td.column-name { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name { + padding-left: 10px; font-weight: bold; } -.path-grade-edit-tree .setup-grades.generaltable tr.category td.column-name div { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div { display: flex; min-height: 30px; align-items: center; } -.path-grade-edit-tree .setup-grades.generaltable tr.item td { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div a.toggle-category { + height: 24px; + width: 24px; + font-size: 12px; + line-height: 24px; + margin-right: 3px; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div a.toggle-category[aria-expanded=true] .expanded, .path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div a.toggle-category[aria-expanded=false] .collapsed { + display: none; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.category td.column-name div a.toggle-category i { + font-size: 12px; + width: 12px; + height: 12px; + color: #1d2125; + margin: 0; +} +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item td { background-color: white; border-top: 3px solid #f8f9fa; } -.path-grade-edit-tree .setup-grades.generaltable tr.item.categoryitem td, .path-grade-edit-tree .setup-grades.generaltable tr.item.courseitem td { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.categoryitem td, .path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.courseitem td { min-width: 4.5em; background-color: #f8f9fa; border: none; vertical-align: middle; } -.path-grade-edit-tree .setup-grades.generaltable tr.item.categoryitem td.column-name, .path-grade-edit-tree .setup-grades.generaltable tr.item.courseitem td.column-name { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.categoryitem td.column-name, .path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.courseitem td.column-name { padding-left: 0; } -.path-grade-edit-tree .setup-grades.generaltable tr.item.categoryitem td:not(.column-actions), .path-grade-edit-tree .setup-grades.generaltable tr.item.courseitem td:not(.column-actions) { +.path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.categoryitem td:not(.column-actions), .path-grade-edit-tree .gradetree-wrapper .setup-grades.generaltable tr.item.courseitem td:not(.column-actions) { font-weight: bold; }