mirror of
https://github.com/moodle/moodle.git
synced 2025-04-25 10:26:17 +02:00
MDL-81043 gradereport_grader: Improve gradereport_grader/collapse
- This will helps `nodesUpdate` handle asynchronous updates better - This also helps to fix Random Behat failure
This commit is contained in:
parent
e6c92dc291
commit
83d9bb6ffb
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -57,6 +57,7 @@ const selectors = {
|
||||
placeholder: '.collapsecolumndropdown [data-region="placeholder"]',
|
||||
fullDropdown: '.collapsecolumndropdown',
|
||||
searchResultContainer: '.searchresultitemscontainer',
|
||||
cellMenuButton: '.cellmenubtn',
|
||||
};
|
||||
|
||||
const countIndicator = document.querySelector(selectors.count);
|
||||
@ -196,6 +197,7 @@ export default class ColumnSearch extends search_combobox {
|
||||
async docClickHandler(e) {
|
||||
if (e.target.dataset.hider === selectors.hider) {
|
||||
e.preventDefault();
|
||||
const pendingPromise = new Pending('gradereport_grader/collapse:docClickHandler:hide');
|
||||
const desiredToHide = e.target.closest(selectors.colVal) ?
|
||||
e.target.closest(selectors.colVal)?.dataset.col :
|
||||
e.target.closest(selectors.itemVal)?.dataset.itemid;
|
||||
@ -205,11 +207,13 @@ export default class ColumnSearch extends search_combobox {
|
||||
}
|
||||
await this.prefcountpipe();
|
||||
|
||||
this.nodesUpdate(desiredToHide);
|
||||
await this.nodesUpdate(desiredToHide);
|
||||
pendingPromise.resolve();
|
||||
}
|
||||
|
||||
if (e.target.closest('button')?.dataset.hider === selectors.expand) {
|
||||
e.preventDefault();
|
||||
const pendingPromise = new Pending('gradereport_grader/collapse:docClickHandler:expand');
|
||||
const desiredToHide = e.target.closest(selectors.colVal) ?
|
||||
e.target.closest(selectors.colVal)?.dataset.col :
|
||||
e.target.closest(selectors.itemVal)?.dataset.itemid;
|
||||
@ -218,8 +222,9 @@ export default class ColumnSearch extends search_combobox {
|
||||
|
||||
await this.prefcountpipe();
|
||||
|
||||
this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.col);
|
||||
this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.itemid);
|
||||
await this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.col);
|
||||
await this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.itemid);
|
||||
pendingPromise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,11 +336,14 @@ export default class ColumnSearch extends search_combobox {
|
||||
});
|
||||
}
|
||||
|
||||
nodesUpdate(item) {
|
||||
async nodesUpdate(item) {
|
||||
const colNodesToHide = [...document.querySelectorAll(`[data-col="${item}"]`)];
|
||||
const itemIDNodesToHide = [...document.querySelectorAll(`[data-itemid="${item}"]`)];
|
||||
this.nodes = [...colNodesToHide, ...itemIDNodesToHide];
|
||||
this.updateDisplay();
|
||||
const elements = [...colNodesToHide, ...itemIDNodesToHide];
|
||||
if (elements && elements.length) {
|
||||
const pendingPromise = new Pending('gradereport_grader/collapse:nodesUpdate:' + item);
|
||||
this.updateDisplay(elements).then(() => pendingPromise.resolve()).catch(Notification.exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -400,52 +408,68 @@ export default class ColumnSearch extends search_combobox {
|
||||
|
||||
/**
|
||||
* With an array of nodes, switch their classes and values.
|
||||
*
|
||||
* @param {Array} elements The elements to update.
|
||||
*/
|
||||
updateDisplay() {
|
||||
this.nodes.forEach((element) => {
|
||||
const content = element.querySelector(selectors.content);
|
||||
const sort = element.querySelector(selectors.sort);
|
||||
const expandButton = element.querySelector(selectors.expandbutton);
|
||||
const rangeRowCell = element.querySelector(selectors.rangerowcell);
|
||||
const avgRowCell = element.querySelector(selectors.avgrowcell);
|
||||
const nodeSet = [
|
||||
element.querySelector(selectors.menu),
|
||||
element.querySelector(selectors.icons),
|
||||
content
|
||||
];
|
||||
|
||||
// This can be further improved to reduce redundant similar calls.
|
||||
if (element.classList.contains('cell')) {
|
||||
// The column is actively being sorted, lets reset that and reload the page.
|
||||
if (sort !== null) {
|
||||
window.location = this.defaultSort;
|
||||
}
|
||||
if (content === null) {
|
||||
// If it's not a content cell, it must be an overall average or a range cell.
|
||||
const rowCell = avgRowCell ?? rangeRowCell;
|
||||
|
||||
rowCell?.classList.toggle('d-none');
|
||||
} else if (content.classList.contains('d-none')) {
|
||||
// We should always have content but some cells do not contain menus or other actions.
|
||||
element.classList.remove('collapsed');
|
||||
// If there are many nodes, apply the following.
|
||||
if (content.childNodes.length > 1) {
|
||||
content.classList.add('d-flex');
|
||||
}
|
||||
nodeSet.forEach(node => {
|
||||
node?.classList.remove('d-none');
|
||||
});
|
||||
expandButton?.classList.add('d-none');
|
||||
} else {
|
||||
element.classList.add('collapsed');
|
||||
content.classList.remove('d-flex');
|
||||
nodeSet.forEach(node => {
|
||||
node?.classList.add('d-none');
|
||||
});
|
||||
expandButton?.classList.remove('d-none');
|
||||
}
|
||||
}
|
||||
async updateDisplay(elements) {
|
||||
const promises = [];
|
||||
elements.forEach((element) => {
|
||||
promises.push(this.updateDisplayForElement(element));
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update display for given element, switch its classes and values.
|
||||
*
|
||||
* @param {HTMLElement} element The element to update.
|
||||
*/
|
||||
async updateDisplayForElement(element) {
|
||||
const content = element.querySelector(selectors.content);
|
||||
const sort = element.querySelector(selectors.sort);
|
||||
const expandButton = element.querySelector(selectors.expandbutton);
|
||||
const rangeRowCell = element.querySelector(selectors.rangerowcell);
|
||||
const avgRowCell = element.querySelector(selectors.avgrowcell);
|
||||
const cellMenuButton = element.querySelector(selectors.cellMenuButton);
|
||||
const nodeSet = [
|
||||
element.querySelector(selectors.menu),
|
||||
element.querySelector(selectors.icons),
|
||||
content
|
||||
];
|
||||
|
||||
// This can be further improved to reduce redundant similar calls.
|
||||
if (element.classList.contains('cell')) {
|
||||
// The column is actively being sorted, lets reset that and reload the page.
|
||||
if (sort !== null) {
|
||||
window.location = this.defaultSort;
|
||||
}
|
||||
if (content === null) {
|
||||
// If it's not a content cell, it must be an overall average or a range cell.
|
||||
const rowCell = avgRowCell ?? rangeRowCell;
|
||||
|
||||
rowCell?.classList.toggle('d-none');
|
||||
} else if (content.classList.contains('d-none')) {
|
||||
// We should always have content but some cells do not contain menus or other actions.
|
||||
element.classList.remove('collapsed');
|
||||
// If there are many nodes, apply the following.
|
||||
if (content.childNodes.length > 1) {
|
||||
content.classList.add('d-flex');
|
||||
}
|
||||
nodeSet.forEach(node => {
|
||||
node?.classList.remove('d-none');
|
||||
});
|
||||
expandButton?.classList.add('d-none');
|
||||
cellMenuButton?.focus();
|
||||
} else {
|
||||
element.classList.add('collapsed');
|
||||
content.classList.remove('d-flex');
|
||||
nodeSet.forEach(node => {
|
||||
node?.classList.add('d-none');
|
||||
});
|
||||
expandButton?.classList.remove('d-none');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user