| Línea 22... |
Línea 22... |
| 22 |
*/
|
22 |
*/
|
| 23 |
import * as Repository from 'gradereport_grader/collapse/repository';
|
23 |
import * as Repository from 'gradereport_grader/collapse/repository';
|
| 24 |
import search_combobox from 'core/comboboxsearch/search_combobox';
|
24 |
import search_combobox from 'core/comboboxsearch/search_combobox';
|
| 25 |
import {renderForPromise, replaceNodeContents, replaceNode} from 'core/templates';
|
25 |
import {renderForPromise, replaceNodeContents, replaceNode} from 'core/templates';
|
| 26 |
import {debounce} from 'core/utils';
|
26 |
import {debounce} from 'core/utils';
|
| 27 |
import $ from 'jquery';
|
27 |
import Dropdown from 'theme_boost/bootstrap/dropdown';
|
| 28 |
import {getStrings} from 'core/str';
|
28 |
import {getStrings} from 'core/str';
|
| 29 |
import CustomEvents from "core/custom_interaction_events";
|
29 |
import CustomEvents from "core/custom_interaction_events";
|
| 30 |
import storage from 'core/localstorage';
|
30 |
import storage from 'core/localstorage';
|
| 31 |
import {addIconToContainer} from 'core/loadingicon';
|
31 |
import {addIconToContainer} from 'core/loadingicon';
|
| 32 |
import Notification from 'core/notification';
|
32 |
import Notification from 'core/notification';
|
| Línea 55... |
Línea 55... |
| 55 |
icons: '.data-collapse_gradeicons',
|
55 |
icons: '.data-collapse_gradeicons',
|
| 56 |
count: '[data-collapse="count"]',
|
56 |
count: '[data-collapse="count"]',
|
| 57 |
placeholder: '.collapsecolumndropdown [data-region="placeholder"]',
|
57 |
placeholder: '.collapsecolumndropdown [data-region="placeholder"]',
|
| 58 |
fullDropdown: '.collapsecolumndropdown',
|
58 |
fullDropdown: '.collapsecolumndropdown',
|
| 59 |
searchResultContainer: '.searchresultitemscontainer',
|
59 |
searchResultContainer: '.searchresultitemscontainer',
|
| - |
|
60 |
cellMenuButton: '.cellmenubtn',
|
| 60 |
};
|
61 |
};
|
| Línea 61... |
Línea 62... |
| 61 |
|
62 |
|
| Línea 62... |
Línea 63... |
| 62 |
const countIndicator = document.querySelector(selectors.count);
|
63 |
const countIndicator = document.querySelector(selectors.count);
|
| Línea 98... |
Línea 99... |
| 98 |
loader.remove();
|
99 |
loader.remove();
|
| 99 |
document.querySelector('.gradereport-grader-table').classList.remove('d-none');
|
100 |
document.querySelector('.gradereport-grader-table').classList.remove('d-none');
|
| 100 |
}, 10);
|
101 |
}, 10);
|
| 101 |
}).then(() => pendingPromise.resolve()).catch(Notification.exception);
|
102 |
}).then(() => pendingPromise.resolve()).catch(Notification.exception);
|
| Línea 102... |
Línea 103... |
| 102 |
|
103 |
|
| 103 |
this.$component.on('hide.bs.dropdown', () => {
|
104 |
this.component.addEventListener('hide.bs.dropdown', () => {
|
| 104 |
const searchResultContainer = this.component.querySelector(selectors.searchResultContainer);
|
105 |
const searchResultContainer = this.component.querySelector(selectors.searchResultContainer);
|
| Línea 105... |
Línea 106... |
| 105 |
searchResultContainer.scrollTop = 0;
|
106 |
searchResultContainer.scrollTop = 0;
|
| 106 |
|
107 |
|
| Línea 194... |
Línea 195... |
| 194 |
* @returns {Promise<void>}
|
195 |
* @returns {Promise<void>}
|
| 195 |
*/
|
196 |
*/
|
| 196 |
async docClickHandler(e) {
|
197 |
async docClickHandler(e) {
|
| 197 |
if (e.target.dataset.hider === selectors.hider) {
|
198 |
if (e.target.dataset.hider === selectors.hider) {
|
| 198 |
e.preventDefault();
|
199 |
e.preventDefault();
|
| - |
|
200 |
const pendingPromise = new Pending('gradereport_grader/collapse:docClickHandler:hide');
|
| 199 |
const desiredToHide = e.target.closest(selectors.colVal) ?
|
201 |
const desiredToHide = e.target.closest(selectors.colVal) ?
|
| 200 |
e.target.closest(selectors.colVal)?.dataset.col :
|
202 |
e.target.closest(selectors.colVal)?.dataset.col :
|
| 201 |
e.target.closest(selectors.itemVal)?.dataset.itemid;
|
203 |
e.target.closest(selectors.itemVal)?.dataset.itemid;
|
| 202 |
const idx = this.getDataset().indexOf(desiredToHide);
|
204 |
const idx = this.getDataset().indexOf(desiredToHide);
|
| 203 |
if (idx === -1) {
|
205 |
if (idx === -1) {
|
| 204 |
this.getDataset().push(desiredToHide);
|
206 |
this.getDataset().push(desiredToHide);
|
| 205 |
}
|
207 |
}
|
| 206 |
await this.prefcountpipe();
|
208 |
await this.prefcountpipe();
|
| Línea 207... |
Línea 209... |
| 207 |
|
209 |
|
| - |
|
210 |
await this.nodesUpdate(desiredToHide);
|
| 208 |
this.nodesUpdate(desiredToHide);
|
211 |
pendingPromise.resolve();
|
| Línea 209... |
Línea 212... |
| 209 |
}
|
212 |
}
|
| 210 |
|
213 |
|
| - |
|
214 |
if (e.target.closest('button')?.dataset.hider === selectors.expand) {
|
| 211 |
if (e.target.closest('button')?.dataset.hider === selectors.expand) {
|
215 |
e.preventDefault();
|
| 212 |
e.preventDefault();
|
216 |
const pendingPromise = new Pending('gradereport_grader/collapse:docClickHandler:expand');
|
| 213 |
const desiredToHide = e.target.closest(selectors.colVal) ?
|
217 |
const desiredToHide = e.target.closest(selectors.colVal) ?
|
| 214 |
e.target.closest(selectors.colVal)?.dataset.col :
|
218 |
e.target.closest(selectors.colVal)?.dataset.col :
|
| 215 |
e.target.closest(selectors.itemVal)?.dataset.itemid;
|
219 |
e.target.closest(selectors.itemVal)?.dataset.itemid;
|
| Línea 216... |
Línea 220... |
| 216 |
const idx = this.getDataset().indexOf(desiredToHide);
|
220 |
const idx = this.getDataset().indexOf(desiredToHide);
|
| Línea 217... |
Línea 221... |
| 217 |
this.getDataset().splice(idx, 1);
|
221 |
this.getDataset().splice(idx, 1);
|
| 218 |
|
222 |
|
| - |
|
223 |
await this.prefcountpipe();
|
| 219 |
await this.prefcountpipe();
|
224 |
|
| 220 |
|
225 |
await this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.col);
|
| Línea 221... |
Línea 226... |
| 221 |
this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.col);
|
226 |
await this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.itemid);
|
| 222 |
this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.itemid);
|
227 |
pendingPromise.resolve();
|
| Línea 312... |
Línea 317... |
| 312 |
});
|
317 |
});
|
| Línea 313... |
Línea 318... |
| 313 |
|
318 |
|
| 314 |
form.addEventListener('submit', async(e) => {
|
319 |
form.addEventListener('submit', async(e) => {
|
| 315 |
e.preventDefault();
|
320 |
e.preventDefault();
|
| 316 |
if (e.submitter.dataset.action === selectors.formItems.cancel) {
|
321 |
if (e.submitter.dataset.action === selectors.formItems.cancel) {
|
| 317 |
$(this.component).dropdown('toggle');
|
322 |
Dropdown.getOrCreateInstance(this.component).toggle();
|
| 318 |
return;
|
323 |
return;
|
| 319 |
}
|
324 |
}
|
| 320 |
// Get the users' checked columns to change.
|
325 |
// Get the users' checked columns to change.
|
| 321 |
const checkedItems = [...form.elements].filter(item => item.checked);
|
326 |
const checkedItems = [...form.elements].filter(item => item.checked);
|
| Línea 329... |
Línea 334... |
| 329 |
e.submitter.disabled = true;
|
334 |
e.submitter.disabled = true;
|
| 330 |
await this.prefcountpipe();
|
335 |
await this.prefcountpipe();
|
| 331 |
});
|
336 |
});
|
| 332 |
}
|
337 |
}
|
| Línea 333... |
Línea 338... |
| 333 |
|
338 |
|
| 334 |
nodesUpdate(item) {
|
339 |
async nodesUpdate(item) {
|
| 335 |
const colNodesToHide = [...document.querySelectorAll(`[data-col="${item}"]`)];
|
340 |
const colNodesToHide = [...document.querySelectorAll(`[data-col="${item}"]`)];
|
| 336 |
const itemIDNodesToHide = [...document.querySelectorAll(`[data-itemid="${item}"]`)];
|
341 |
const itemIDNodesToHide = [...document.querySelectorAll(`[data-itemid="${item}"]`)];
|
| 337 |
this.nodes = [...colNodesToHide, ...itemIDNodesToHide];
|
342 |
const elements = [...colNodesToHide, ...itemIDNodesToHide];
|
| - |
|
343 |
if (elements && elements.length) {
|
| - |
|
344 |
const pendingPromise = new Pending('gradereport_grader/collapse:nodesUpdate:' + item);
|
| - |
|
345 |
this.updateDisplay(elements).then(() => pendingPromise.resolve()).catch(Notification.exception);
|
| 338 |
this.updateDisplay();
|
346 |
}
|
| Línea 339... |
Línea 347... |
| 339 |
}
|
347 |
}
|
| 340 |
|
348 |
|
| 341 |
/**
|
349 |
/**
|
| Línea 398... |
Línea 406... |
| 398 |
);
|
406 |
);
|
| 399 |
}
|
407 |
}
|
| Línea 400... |
Línea 408... |
| 400 |
|
408 |
|
| 401 |
/**
|
409 |
/**
|
| - |
|
410 |
* With an array of nodes, switch their classes and values.
|
| - |
|
411 |
*
|
| 402 |
* With an array of nodes, switch their classes and values.
|
412 |
* @param {Array} elements The elements to update.
|
| 403 |
*/
|
413 |
*/
|
| - |
|
414 |
async updateDisplay(elements) {
|
| 404 |
updateDisplay() {
|
415 |
const promises = [];
|
| - |
|
416 |
elements.forEach((element) => {
|
| - |
|
417 |
promises.push(this.updateDisplayForElement(element));
|
| - |
|
418 |
});
|
| - |
|
419 |
|
| - |
|
420 |
await Promise.all(promises);
|
| - |
|
421 |
}
|
| - |
|
422 |
|
| - |
|
423 |
/**
|
| - |
|
424 |
* Update display for given element, switch its classes and values.
|
| - |
|
425 |
*
|
| - |
|
426 |
* @param {HTMLElement} element The element to update.
|
| - |
|
427 |
*/
|
| 405 |
this.nodes.forEach((element) => {
|
428 |
async updateDisplayForElement(element) {
|
| 406 |
const content = element.querySelector(selectors.content);
|
429 |
const content = element.querySelector(selectors.content);
|
| 407 |
const sort = element.querySelector(selectors.sort);
|
430 |
const sort = element.querySelector(selectors.sort);
|
| 408 |
const expandButton = element.querySelector(selectors.expandbutton);
|
431 |
const expandButton = element.querySelector(selectors.expandbutton);
|
| 409 |
const rangeRowCell = element.querySelector(selectors.rangerowcell);
|
432 |
const rangeRowCell = element.querySelector(selectors.rangerowcell);
|
| - |
|
433 |
const avgRowCell = element.querySelector(selectors.avgrowcell);
|
| 410 |
const avgRowCell = element.querySelector(selectors.avgrowcell);
|
434 |
const cellMenuButton = element.querySelector(selectors.cellMenuButton);
|
| 411 |
const nodeSet = [
|
435 |
const nodeSet = [
|
| 412 |
element.querySelector(selectors.menu),
|
436 |
element.querySelector(selectors.menu),
|
| 413 |
element.querySelector(selectors.icons),
|
437 |
element.querySelector(selectors.icons),
|
| 414 |
content
|
438 |
content
|
| 415 |
];
|
439 |
];
|
| 416 |
|
440 |
|
| 417 |
// This can be further improved to reduce redundant similar calls.
|
441 |
// This can be further improved to reduce redundant similar calls.
|
| 418 |
if (element.classList.contains('cell')) {
|
442 |
if (element.classList.contains('cell')) {
|
| 419 |
// The column is actively being sorted, lets reset that and reload the page.
|
443 |
// The column is actively being sorted, lets reset that and reload the page.
|
| 420 |
if (sort !== null) {
|
444 |
if (sort !== null) {
|
| 421 |
window.location = this.defaultSort;
|
445 |
window.location = this.defaultSort;
|
| 422 |
}
|
446 |
}
|
| 423 |
if (content === null) {
|
447 |
if (content === null) {
|
| 424 |
// If it's not a content cell, it must be an overall average or a range cell.
|
448 |
// If it's not a content cell, it must be an overall average or a range cell.
|
| 425 |
const rowCell = avgRowCell ?? rangeRowCell;
|
449 |
const rowCell = avgRowCell ?? rangeRowCell;
|
| 426 |
|
450 |
|
| 427 |
rowCell?.classList.toggle('d-none');
|
451 |
rowCell?.classList.toggle('d-none');
|
| 428 |
} else if (content.classList.contains('d-none')) {
|
452 |
} else if (content.classList.contains('d-none')) {
|
| 429 |
// We should always have content but some cells do not contain menus or other actions.
|
453 |
// We should always have content but some cells do not contain menus or other actions.
|
| 430 |
element.classList.remove('collapsed');
|
454 |
element.classList.remove('collapsed');
|
| 431 |
// If there are many nodes, apply the following.
|
455 |
// If there are many nodes, apply the following.
|
| 432 |
if (content.childNodes.length > 1) {
|
456 |
if (content.childNodes.length > 1) {
|
| 433 |
content.classList.add('d-flex');
|
- |
|
| 434 |
}
|
- |
|
| 435 |
nodeSet.forEach(node => {
|
- |
|
| 436 |
node?.classList.remove('d-none');
|
- |
|
| 437 |
});
|
- |
|
| 438 |
expandButton?.classList.add('d-none');
|
- |
|
| 439 |
} else {
|
- |
|
| 440 |
element.classList.add('collapsed');
|
- |
|
| 441 |
content.classList.remove('d-flex');
|
- |
|
| 442 |
nodeSet.forEach(node => {
|
- |
|
| 443 |
node?.classList.add('d-none');
|
- |
|
| 444 |
});
|
- |
|
| 445 |
expandButton?.classList.remove('d-none');
|
457 |
content.classList.add('d-flex');
|
| - |
|
458 |
}
|
| - |
|
459 |
nodeSet.forEach(node => {
|
| - |
|
460 |
node?.classList.remove('d-none');
|
| - |
|
461 |
});
|
| - |
|
462 |
expandButton?.classList.add('d-none');
|
| - |
|
463 |
cellMenuButton?.focus();
|
| - |
|
464 |
} else {
|
| - |
|
465 |
element.classList.add('collapsed');
|
| - |
|
466 |
content.classList.remove('d-flex');
|
| - |
|
467 |
nodeSet.forEach(node => {
|
| - |
|
468 |
node?.classList.add('d-none');
|
| - |
|
469 |
});
|
| 446 |
}
|
470 |
expandButton?.classList.remove('d-none');
|
| 447 |
}
|
471 |
}
|
| 448 |
});
|
472 |
}
|
| Línea 449... |
Línea 473... |
| 449 |
}
|
473 |
}
|
| 450 |
|
474 |
|
| 451 |
/**
|
475 |
/**
|
| Línea 482... |
Línea 506... |
| 482 |
// Given we now have the body, we can set up more triggers.
|
506 |
// Given we now have the body, we can set up more triggers.
|
| 483 |
this.registerFormEvents();
|
507 |
this.registerFormEvents();
|
| 484 |
this.registerInputEvents();
|
508 |
this.registerInputEvents();
|
| Línea 485... |
Línea 509... |
| 485 |
|
509 |
|
| 486 |
// Add a small BS listener so that we can set the focus correctly on open.
|
510 |
// Add a small BS listener so that we can set the focus correctly on open.
|
| 487 |
this.$component.on('shown.bs.dropdown', () => {
|
511 |
this.component.addEventListener('shown.bs.dropdown', () => {
|
| 488 |
this.searchInput.focus({preventScroll: true});
|
512 |
this.searchInput.focus({preventScroll: true});
|
| 489 |
this.selectallEnable();
|
513 |
this.selectallEnable();
|
| 490 |
});
|
514 |
});
|