diff --git a/grade/report/grader/amd/build/stickycolspan.min.js b/grade/report/grader/amd/build/stickycolspan.min.js index ff7c6a6f75b..380ff0c5fb0 100644 --- a/grade/report/grader/amd/build/stickycolspan.min.js +++ b/grade/report/grader/amd/build/stickycolspan.min.js @@ -1,11 +1,10 @@ -define("gradereport_grader/stickycolspan",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0; +define("gradereport_grader/stickycolspan",["exports","jquery"],(function(_exports,_jquery){var obj; /** * Javascript module for fixing the position of sticky headers with multiple colspans * * @module gradereport_grader/stickycolspan * @copyright 2022 Bas Brands * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -const SELECTORS_GRADEPARENT=".gradeparent",SELECTORS_STUDENTHEADER="#studentheader",SELECTORS_TABLEHEADER="th.header",SELECTORS_BEHAT="body.behat-site",SELECTORS_TABLEHEADING="tr.heading",SELECTORS_GRADERDROPDOWN="tr th.category .dropdown-menu";_exports.init=()=>{const grader=document.querySelector(SELECTORS_GRADEPARENT),tableHeaders=grader.querySelectorAll(SELECTORS_TABLEHEADER);let i=0;tableHeaders.forEach((tableHeader=>{tableHeader.colSpan<=1&&(tableHeader.style.zIndex=tableHeaders.length-i),i++}));const categoryDropdowns=grader.querySelectorAll(SELECTORS_GRADERDROPDOWN);categoryDropdowns.forEach((dropdown=>{dropdown.style.zIndex=tableHeaders.length+categoryDropdowns.length+1}));if(grader.querySelector(SELECTORS_TABLEHEADING).style.zIndex=tableHeaders.length+1,!document.querySelector(SELECTORS_BEHAT)){const studentHeader=grader.querySelector(SELECTORS_STUDENTHEADER),leftOffset=getComputedStyle(studentHeader).getPropertyValue("left"),rightOffset=getComputedStyle(studentHeader).getPropertyValue("right");tableHeaders.forEach((tableHeader=>{if(tableHeader.colSpan>1){const addOffset=tableHeader.offsetWidth-studentHeader.offsetWidth;window.right_to_left()?tableHeader.style.right="calc("+rightOffset+" - "+addOffset+"px )":tableHeader.style.left="calc("+leftOffset+" - "+addOffset+"px )"}}))}}})); + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_jquery=(obj=_jquery)&&obj.__esModule?obj:{default:obj};const SELECTORS_GRADEPARENT=".gradeparent",SELECTORS_STUDENTHEADER="#studentheader",SELECTORS_TABLEHEADER="th.header",SELECTORS_BEHAT="body.behat-site",SELECTORS_USERDROPDOWN=".userrow th .dropdown",SELECTORS_AVERAGEROWHEADER=".lastrow th";_exports.init=()=>{(0,_jquery.default)(SELECTORS_USERDROPDOWN).on("show.bs.dropdown hide.bs.dropdown",(e=>{e.target.closest(SELECTORS_TABLEHEADER).classList.toggle("actions-menu-active")}));if(new IntersectionObserver((_ref=>{let[e]=_ref;return e.target.closest("tr").classList.toggle("pinned",e.intersectionRatio<1)}),{threshold:[1]}).observe(document.querySelector(SELECTORS_AVERAGEROWHEADER)),!document.querySelector(SELECTORS_BEHAT)){const grader=document.querySelector(SELECTORS_GRADEPARENT),tableHeaders=grader.querySelectorAll(SELECTORS_TABLEHEADER),studentHeader=grader.querySelector(SELECTORS_STUDENTHEADER),leftOffset=getComputedStyle(studentHeader).getPropertyValue("left"),rightOffset=getComputedStyle(studentHeader).getPropertyValue("right");tableHeaders.forEach((tableHeader=>{if(tableHeader.colSpan>1){const addOffset=tableHeader.offsetWidth-studentHeader.offsetWidth;window.right_to_left()?tableHeader.style.right="calc("+rightOffset+" - "+addOffset+"px )":tableHeader.style.left="calc("+leftOffset+" - "+addOffset+"px )"}}))}}})); //# sourceMappingURL=stickycolspan.min.js.map \ No newline at end of file diff --git a/grade/report/grader/amd/build/stickycolspan.min.js.map b/grade/report/grader/amd/build/stickycolspan.min.js.map index b0256675426..48523d6faa7 100644 --- a/grade/report/grader/amd/build/stickycolspan.min.js.map +++ b/grade/report/grader/amd/build/stickycolspan.min.js.map @@ -1 +1 @@ -{"version":3,"file":"stickycolspan.min.js","sources":["../src/stickycolspan.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 * Javascript module for fixing the position of sticky headers with multiple colspans\n *\n * @module gradereport_grader/stickycolspan\n * @copyright 2022 Bas Brands \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst SELECTORS = {\n GRADEPARENT: '.gradeparent',\n STUDENTHEADER: '#studentheader',\n TABLEHEADER: 'th.header',\n BEHAT: 'body.behat-site',\n AVERAGEROW: 'tr.lastrow',\n TABLEHEADING: 'tr.heading',\n GRADERDROPDOWN: 'tr th.category .dropdown-menu',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n const grader = document.querySelector(SELECTORS.GRADEPARENT);\n const tableHeaders = grader.querySelectorAll(SELECTORS.TABLEHEADER);\n\n let i = 0;\n tableHeaders.forEach((tableHeader) => {\n if (tableHeader.colSpan <= 1) {\n tableHeader.style.zIndex = tableHeaders.length - i;\n }\n i++;\n });\n\n const categoryDropdowns = grader.querySelectorAll(SELECTORS.GRADERDROPDOWN);\n categoryDropdowns.forEach(dropdown => {\n // Ensure we take all the displayed users + any & all categories and add a bit extra for safe measure.\n dropdown.style.zIndex = (tableHeaders.length + categoryDropdowns.length) + 1;\n });\n\n const tableHeader = grader.querySelector(SELECTORS.TABLEHEADING);\n tableHeader.style.zIndex = tableHeaders.length + 1;\n\n if (!document.querySelector(SELECTORS.BEHAT)) {\n const studentHeader = grader.querySelector(SELECTORS.STUDENTHEADER);\n const leftOffset = getComputedStyle(studentHeader).getPropertyValue('left');\n const rightOffset = getComputedStyle(studentHeader).getPropertyValue('right');\n\n tableHeaders.forEach((tableHeader) => {\n if (tableHeader.colSpan > 1) {\n const addOffset = (tableHeader.offsetWidth - studentHeader.offsetWidth);\n if (window.right_to_left()) {\n tableHeader.style.right = 'calc(' + rightOffset + ' - ' + addOffset + 'px )';\n } else {\n tableHeader.style.left = 'calc(' + leftOffset + ' - ' + addOffset + 'px )';\n }\n }\n });\n }\n};\n"],"names":["SELECTORS","grader","document","querySelector","tableHeaders","querySelectorAll","i","forEach","tableHeader","colSpan","style","zIndex","length","categoryDropdowns","dropdown","studentHeader","leftOffset","getComputedStyle","getPropertyValue","rightOffset","addOffset","offsetWidth","window","right_to_left","right","left"],"mappings":";;;;;;;;MAuBMA,sBACW,eADXA,wBAEa,iBAFbA,sBAGW,YAHXA,gBAIK,kBAJLA,uBAMY,aANZA,yBAOc,8CAMA,WACVC,OAASC,SAASC,cAAcH,uBAChCI,aAAeH,OAAOI,iBAAiBL,2BAEzCM,EAAI,EACRF,aAAaG,SAASC,cACdA,YAAYC,SAAW,IACvBD,YAAYE,MAAMC,OAASP,aAAaQ,OAASN,GAErDA,aAGEO,kBAAoBZ,OAAOI,iBAAiBL,0BAClDa,kBAAkBN,SAAQO,WAEtBA,SAASJ,MAAMC,OAAUP,aAAaQ,OAASC,kBAAkBD,OAAU,QAG3DX,OAAOE,cAAcH,wBAC7BU,MAAMC,OAASP,aAAaQ,OAAS,GAE5CV,SAASC,cAAcH,iBAAkB,OACpCe,cAAgBd,OAAOE,cAAcH,yBACrCgB,WAAaC,iBAAiBF,eAAeG,iBAAiB,QAC9DC,YAAcF,iBAAiBF,eAAeG,iBAAiB,SAErEd,aAAaG,SAASC,iBACdA,YAAYC,QAAU,EAAG,OACnBW,UAAaZ,YAAYa,YAAcN,cAAcM,YACvDC,OAAOC,gBACPf,YAAYE,MAAMc,MAAQ,QAAUL,YAAc,MAAQC,UAAY,OAEtEZ,YAAYE,MAAMe,KAAO,QAAUT,WAAa,MAAQI,UAAY"} \ No newline at end of file +{"version":3,"file":"stickycolspan.min.js","sources":["../src/stickycolspan.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 * Javascript module for fixing the position of sticky headers with multiple colspans\n *\n * @module gradereport_grader/stickycolspan\n * @copyright 2022 Bas Brands \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\n\nconst SELECTORS = {\n GRADEPARENT: '.gradeparent',\n STUDENTHEADER: '#studentheader',\n TABLEHEADER: 'th.header',\n BEHAT: 'body.behat-site',\n USERDROPDOWN: '.userrow th .dropdown',\n AVERAGEROWHEADER: '.lastrow th',\n};\n\n/**\n * Initialize module\n */\nexport const init = () => {\n // The sticky positioning attributed to the user column cells affects the stacking context and makes the dropdowns\n // within these cells to be cut off. To solve this problem, whenever one of these action menus (dropdowns) is opened\n // we need to manually bump up the z-index value of the parent container element and revert once closed.\n $(SELECTORS.USERDROPDOWN).on('show.bs.dropdown hide.bs.dropdown', (e) => {\n // The closest heading element has sticky positioning which affects the stacking context in this case.\n e.target.closest(SELECTORS.TABLEHEADER).classList.toggle('actions-menu-active');\n });\n // Register an observer that will bump up the z-index value of the average overall row when it's pinned to prevent\n // the row being cut-off by the user column cells or other components within the report table that have higher\n // z-index values.\n const observer = new IntersectionObserver(\n ([e]) => e.target.closest('tr').classList.toggle('pinned', e.intersectionRatio < 1),\n {threshold: [1]}\n );\n observer.observe(document.querySelector(SELECTORS.AVERAGEROWHEADER));\n\n if (!document.querySelector(SELECTORS.BEHAT)) {\n const grader = document.querySelector(SELECTORS.GRADEPARENT);\n const tableHeaders = grader.querySelectorAll(SELECTORS.TABLEHEADER);\n const studentHeader = grader.querySelector(SELECTORS.STUDENTHEADER);\n const leftOffset = getComputedStyle(studentHeader).getPropertyValue('left');\n const rightOffset = getComputedStyle(studentHeader).getPropertyValue('right');\n\n tableHeaders.forEach((tableHeader) => {\n if (tableHeader.colSpan > 1) {\n const addOffset = (tableHeader.offsetWidth - studentHeader.offsetWidth);\n if (window.right_to_left()) {\n tableHeader.style.right = 'calc(' + rightOffset + ' - ' + addOffset + 'px )';\n } else {\n tableHeader.style.left = 'calc(' + leftOffset + ' - ' + addOffset + 'px )';\n }\n }\n });\n }\n};\n"],"names":["SELECTORS","on","e","target","closest","classList","toggle","IntersectionObserver","_ref","intersectionRatio","threshold","observe","document","querySelector","grader","tableHeaders","querySelectorAll","studentHeader","leftOffset","getComputedStyle","getPropertyValue","rightOffset","forEach","tableHeader","colSpan","addOffset","offsetWidth","window","right_to_left","style","right","left"],"mappings":";;;;;;;gJAyBMA,sBACW,eADXA,wBAEa,iBAFbA,sBAGW,YAHXA,gBAIK,kBAJLA,uBAKY,wBALZA,2BAMgB,4BAMF,yBAIdA,wBAAwBC,GAAG,qCAAsCC,IAE/DA,EAAEC,OAAOC,QAAQJ,uBAAuBK,UAAUC,OAAO,6BAK5C,IAAIC,sBACjBC,WAAEN,eAAOA,EAAEC,OAAOC,QAAQ,MAAMC,UAAUC,OAAO,SAAUJ,EAAEO,kBAAoB,KACjF,CAACC,UAAW,CAAC,KAERC,QAAQC,SAASC,cAAcb,8BAEnCY,SAASC,cAAcb,iBAAkB,OACpCc,OAASF,SAASC,cAAcb,uBAChCe,aAAeD,OAAOE,iBAAiBhB,uBACvCiB,cAAgBH,OAAOD,cAAcb,yBACrCkB,WAAaC,iBAAiBF,eAAeG,iBAAiB,QAC9DC,YAAcF,iBAAiBF,eAAeG,iBAAiB,SAErEL,aAAaO,SAASC,iBACdA,YAAYC,QAAU,EAAG,OACnBC,UAAaF,YAAYG,YAAcT,cAAcS,YACvDC,OAAOC,gBACPL,YAAYM,MAAMC,MAAQ,QAAUT,YAAc,MAAQI,UAAY,OAEtEF,YAAYM,MAAME,KAAO,QAAUb,WAAa,MAAQO,UAAY"} \ No newline at end of file diff --git a/grade/report/grader/amd/src/stickycolspan.js b/grade/report/grader/amd/src/stickycolspan.js index d4a1f871839..456b2cc79f4 100644 --- a/grade/report/grader/amd/src/stickycolspan.js +++ b/grade/report/grader/amd/src/stickycolspan.js @@ -21,41 +21,40 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +import $ from 'jquery'; + const SELECTORS = { GRADEPARENT: '.gradeparent', STUDENTHEADER: '#studentheader', TABLEHEADER: 'th.header', BEHAT: 'body.behat-site', - AVERAGEROW: 'tr.lastrow', - TABLEHEADING: 'tr.heading', - GRADERDROPDOWN: 'tr th.category .dropdown-menu', + USERDROPDOWN: '.userrow th .dropdown', + AVERAGEROWHEADER: '.lastrow th', }; /** * Initialize module */ export const init = () => { - const grader = document.querySelector(SELECTORS.GRADEPARENT); - const tableHeaders = grader.querySelectorAll(SELECTORS.TABLEHEADER); - - let i = 0; - tableHeaders.forEach((tableHeader) => { - if (tableHeader.colSpan <= 1) { - tableHeader.style.zIndex = tableHeaders.length - i; - } - i++; + // The sticky positioning attributed to the user column cells affects the stacking context and makes the dropdowns + // within these cells to be cut off. To solve this problem, whenever one of these action menus (dropdowns) is opened + // we need to manually bump up the z-index value of the parent container element and revert once closed. + $(SELECTORS.USERDROPDOWN).on('show.bs.dropdown hide.bs.dropdown', (e) => { + // The closest heading element has sticky positioning which affects the stacking context in this case. + e.target.closest(SELECTORS.TABLEHEADER).classList.toggle('actions-menu-active'); }); - - const categoryDropdowns = grader.querySelectorAll(SELECTORS.GRADERDROPDOWN); - categoryDropdowns.forEach(dropdown => { - // Ensure we take all the displayed users + any & all categories and add a bit extra for safe measure. - dropdown.style.zIndex = (tableHeaders.length + categoryDropdowns.length) + 1; - }); - - const tableHeader = grader.querySelector(SELECTORS.TABLEHEADING); - tableHeader.style.zIndex = tableHeaders.length + 1; + // Register an observer that will bump up the z-index value of the average overall row when it's pinned to prevent + // the row being cut-off by the user column cells or other components within the report table that have higher + // z-index values. + const observer = new IntersectionObserver( + ([e]) => e.target.closest('tr').classList.toggle('pinned', e.intersectionRatio < 1), + {threshold: [1]} + ); + observer.observe(document.querySelector(SELECTORS.AVERAGEROWHEADER)); if (!document.querySelector(SELECTORS.BEHAT)) { + const grader = document.querySelector(SELECTORS.GRADEPARENT); + const tableHeaders = grader.querySelectorAll(SELECTORS.TABLEHEADER); const studentHeader = grader.querySelector(SELECTORS.STUDENTHEADER); const leftOffset = getComputedStyle(studentHeader).getPropertyValue('left'); const rightOffset = getComputedStyle(studentHeader).getPropertyValue('right'); diff --git a/theme/boost/scss/moodle/grade.scss b/theme/boost/scss/moodle/grade.scss index 1d8325928f1..238afbf84c1 100644 --- a/theme/boost/scss/moodle/grade.scss +++ b/theme/boost/scss/moodle/grade.scss @@ -498,10 +498,17 @@ */ .path-grade-report-grader { .gradeparent { - z-index: 5; tr .cell, .floater .cell { background-color: $pagination-bg; + + &.gradecell { + .dropdown-menu { + &.show { + z-index: 1; + } + } + } } table, @@ -522,12 +529,27 @@ tr.heading { position: sticky; top: 0; - z-index: 1; + z-index: 4; + } + + tr.userrow { + th { + z-index: 2; + + &.actions-menu-active { + z-index: 3; + } + } } tr.lastrow { position: sticky; - bottom: 0; + // Hack used by the observer to help detecting when the sticky 'Overall average' row is pinned. */ + bottom: -1px; + + &.pinned { + z-index: 4; + } td, th { @@ -543,7 +565,10 @@ left: -3rem; } position: sticky; - z-index: 1; + + &#studentheader { + z-index: 1; + } } td.noborder { diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index 7ba28b3aabe..384dc354f9e 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -34952,13 +34952,14 @@ p.arrow_button { /** * Grader report. */ -.path-grade-report-grader .gradeparent { - z-index: 5; -} .path-grade-report-grader .gradeparent tr .cell, .path-grade-report-grader .gradeparent .floater .cell { background-color: #fff; } +.path-grade-report-grader .gradeparent tr .cell.gradecell .dropdown-menu.show, +.path-grade-report-grader .gradeparent .floater .cell.gradecell .dropdown-menu.show { + z-index: 1; +} .path-grade-report-grader .gradeparent table, .path-grade-report-grader .gradeparent .cell { border-color: #dee2e6; @@ -34974,11 +34975,20 @@ p.arrow_button { .path-grade-report-grader .gradeparent tr.heading { position: sticky; top: 0; - z-index: 1; + z-index: 4; +} +.path-grade-report-grader .gradeparent tr.userrow th { + z-index: 2; +} +.path-grade-report-grader .gradeparent tr.userrow th.actions-menu-active { + z-index: 3; } .path-grade-report-grader .gradeparent tr.lastrow { position: sticky; - bottom: 0; + bottom: -1px; +} +.path-grade-report-grader .gradeparent tr.lastrow.pinned { + z-index: 4; } .path-grade-report-grader .gradeparent tr.lastrow td, .path-grade-report-grader .gradeparent tr.lastrow th { @@ -34986,7 +34996,6 @@ p.arrow_button { } .path-grade-report-grader .gradeparent th.header { position: sticky; - z-index: 1; } @media (max-width: 767.98px) { .path-grade-report-grader .gradeparent th.header { @@ -34998,6 +35007,9 @@ p.arrow_button { left: -3rem; } } +.path-grade-report-grader .gradeparent th.header#studentheader { + z-index: 1; +} .path-grade-report-grader .gradeparent td.noborder { border-right: transparent; } diff --git a/theme/classic/style/moodle.css b/theme/classic/style/moodle.css index 97b143cb0d3..88e2dc8d6b9 100644 --- a/theme/classic/style/moodle.css +++ b/theme/classic/style/moodle.css @@ -34952,13 +34952,14 @@ p.arrow_button { /** * Grader report. */ -.path-grade-report-grader .gradeparent { - z-index: 5; -} .path-grade-report-grader .gradeparent tr .cell, .path-grade-report-grader .gradeparent .floater .cell { background-color: #fff; } +.path-grade-report-grader .gradeparent tr .cell.gradecell .dropdown-menu.show, +.path-grade-report-grader .gradeparent .floater .cell.gradecell .dropdown-menu.show { + z-index: 1; +} .path-grade-report-grader .gradeparent table, .path-grade-report-grader .gradeparent .cell { border-color: #dee2e6; @@ -34974,11 +34975,20 @@ p.arrow_button { .path-grade-report-grader .gradeparent tr.heading { position: sticky; top: 0; - z-index: 1; + z-index: 4; +} +.path-grade-report-grader .gradeparent tr.userrow th { + z-index: 2; +} +.path-grade-report-grader .gradeparent tr.userrow th.actions-menu-active { + z-index: 3; } .path-grade-report-grader .gradeparent tr.lastrow { position: sticky; - bottom: 0; + bottom: -1px; +} +.path-grade-report-grader .gradeparent tr.lastrow.pinned { + z-index: 4; } .path-grade-report-grader .gradeparent tr.lastrow td, .path-grade-report-grader .gradeparent tr.lastrow th { @@ -34986,7 +34996,6 @@ p.arrow_button { } .path-grade-report-grader .gradeparent th.header { position: sticky; - z-index: 1; } @media (max-width: 767.98px) { .path-grade-report-grader .gradeparent th.header { @@ -34998,6 +35007,9 @@ p.arrow_button { left: -3rem; } } +.path-grade-report-grader .gradeparent th.header#studentheader { + z-index: 1; +} .path-grade-report-grader .gradeparent td.noborder { border-right: transparent; }