Skip to content

Commit

Permalink
MDL-78101 gradereport_grader: Select all collapsed columns functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Chocolate-lightning committed Aug 2, 2023
1 parent a1d5d1b commit 5282ddd
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 15 deletions.
2 changes: 1 addition & 1 deletion grade/report/grader/amd/build/collapse.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion grade/report/grader/amd/build/collapse.min.js.map

Large diffs are not rendered by default.

45 changes: 38 additions & 7 deletions grade/report/grader/amd/src/collapse.js
Expand Up @@ -39,7 +39,8 @@ const selectors = {
formItems: {
cancel: 'cancel',
save: 'save',
checked: 'input[type="checkbox"]:checked'
checked: 'input[type="checkbox"]:checked',
currentlyUnchecked: 'input[type="checkbox"]:not([data-action="selectall"])',
},
hider: 'hide',
expand: 'expand',
Expand Down Expand Up @@ -197,7 +198,7 @@ export default class ColumnSearch extends GradebookSearchClass {
if (idx === -1) {
this.getDataset().push(desiredToHide);
}
await this.prefcountpippe();
await this.prefcountpipe();

this.nodesUpdate(desiredToHide);
}
Expand All @@ -210,7 +211,7 @@ export default class ColumnSearch extends GradebookSearchClass {
const idx = this.getDataset().indexOf(desiredToHide);
this.getDataset().splice(idx, 1);

await this.prefcountpippe();
await this.prefcountpipe();

this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.col);
this.nodesUpdate(e.target.closest(selectors.colVal)?.dataset.itemid);
Expand Down Expand Up @@ -268,13 +269,20 @@ export default class ColumnSearch extends GradebookSearchClass {
];
CustomEvents.define(document, events);

const selectall = form.querySelector('[data-action="selectall"]');

// Register clicks & keyboard form handling.
events.forEach((event) => {
const submitBtn = form.querySelector(`[data-action="${selectors.formItems.save}"`);
form.addEventListener(event, (e) => {
// Stop Bootstrap from being clever.
e.stopPropagation();
const submitBtn = form.querySelector(`[data-action="${selectors.formItems.save}"`);
if (e.target.closest('input')) {
const input = e.target.closest('input');
if (input) {
// If the user is unchecking an item, we need to uncheck the select all if it's checked.
if (selectall.checked && !input.checked) {
selectall.checked = false;
}
const checkedCount = Array.from(form.querySelectorAll(selectors.formItems.checked)).length;
// Check if any are clicked or not then change disabled.
submitBtn.disabled = checkedCount <= 0;
Expand All @@ -289,6 +297,23 @@ export default class ColumnSearch extends GradebookSearchClass {
this.setSearchTerms(this.searchInput.value);
await this.filterrenderpipe();
});
selectall.addEventListener(event, (e) => {
// Stop Bootstrap from being clever.
e.stopPropagation();
if (!selectall.checked) {
const touncheck = Array.from(form.querySelectorAll(selectors.formItems.checked));
touncheck.forEach(item => {
item.checked = false;
});
submitBtn.disabled = true;
} else {
const currentUnchecked = Array.from(form.querySelectorAll(selectors.formItems.currentlyUnchecked));
currentUnchecked.forEach(item => {
item.checked = true;
});
submitBtn.disabled = false;
}
});
});

form.addEventListener('submit', async(e) => {
Expand All @@ -304,7 +329,10 @@ export default class ColumnSearch extends GradebookSearchClass {
this.getDataset().splice(idx, 1);
this.nodesUpdate(item.dataset.collapse);
});
await this.prefcountpippe();
// Reset the check all & submit to false just in case.
selectall.checked = false;
e.submitter.disabled = true;
await this.prefcountpipe();
});
}

Expand All @@ -320,7 +348,7 @@ export default class ColumnSearch extends GradebookSearchClass {
*
* @returns {Promise<void>}
*/
async prefcountpippe() {
async prefcountpipe() {
this.setPreferences();
this.countUpdate();
await this.filterrenderpipe();
Expand Down Expand Up @@ -487,10 +515,13 @@ export default class ColumnSearch extends GradebookSearchClass {
* Build the content then replace the node.
*/
async renderDropdown() {
const form = this.component.querySelector(selectors.formDropdown);
const selectall = form.querySelector('[data-action="selectall"]');
const {html, js} = await renderForPromise('gradereport_grader/collapse/collapseresults', {
'results': this.getMatchedResults(),
'searchTerm': this.getSearchTerm(),
});
selectall.disabled = this.getMatchedResults().length === 0;
replaceNodeContents(this.getHTMLElements().searchDropdown, html, js);
}

Expand Down
2 changes: 1 addition & 1 deletion grade/report/grader/styles.css
Expand Up @@ -267,6 +267,6 @@
}

.collapsecolumndropdown.show {
width: 275px;
width: 300px;
max-height: 300px;
}
16 changes: 13 additions & 3 deletions grade/report/grader/templates/collapse/collapsebody.mustache
Expand Up @@ -45,9 +45,19 @@
<ul class="searchresultitemscontainer overflow-auto py-2 px-1 list-group mx-0 text-truncate" role="listbox" data-region="search-result-items-container" tabindex="-1">
{{>gradereport_grader/collapse/collapseresults}}
</ul>
<div class="d-flex flex-row justify-content-end mt-2">
<input class="btn btn-outline-secondary pull-right mx-2" data-action="cancel" type="submit" value="{{#str}}closebuttontitle{{/str}}">
<input disabled class="btn btn-primary pull-right" data-action="save" type="submit" value="{{#str}}expand{{/str}}">
<div class="d-flex px-1 mt-2">
<div class="d-flex align-items-center form-check">
<input disabled id="check-all-input" class="btn form-check-input" type="checkbox" value="" role="option" data-action="selectall" aria-labelledby="check-all">
<label id="check-all" class="selected-option-info text-truncate form-check-label" tabindex="-1" aria-label="{{#str}}selectall, core{{/str}}">
<span class="selected-option-text w-100 p-0">
{{#str}}selectall, core{{/str}}
</span>
</label>
</div>
<div class="flex-row ml-auto">
<input class="btn btn-outline-secondary pull-right mx-2" data-action="cancel" type="submit" value="{{#str}}closebuttontitle{{/str}}">
<input disabled class="btn btn-primary pull-right" data-action="save" type="submit" value="{{#str}}expand{{/str}}">
</div>
</div>
</form>
</div>
40 changes: 38 additions & 2 deletions grade/report/grader/tests/behat/column_collapsing.feature
Expand Up @@ -192,11 +192,11 @@ Feature: Within the grader report, test that we can collapse columns
And I press the down key
And the focused element is "Email address" "option_role"
And I press the end key
And the focused element is "Country" "option_role"
And the focused element is "Select all" "option_role"
And I press the home key
And the focused element is "Email address" "option_role"
And I press the up key
And the focused element is "Country" "option_role"
And the focused element is "Select all" "option_role"
And I press the down key
And the focused element is "Email address" "option_role"
And I press the escape key
Expand All @@ -214,6 +214,7 @@ Feature: Within the grader report, test that we can collapse columns
And I press the tab key
And I press the tab key
And I press the tab key
And I press the tab key
And the focused element is "Close" "button" in the ".dropdown-menu.show" "css_element"
And I press the tab key
# The course grade category menu.
Expand Down Expand Up @@ -273,3 +274,38 @@ Feature: Within the grader report, test that we can collapse columns
Then "Dummy User" "table_row" should appear before "Student 1" "table_row"
And "Student 1" "table_row" should appear before "Turtle Manatee" "table_row"
And "Turtle Manatee" "table_row" should appear before "User Example" "table_row"

Scenario: If multiple columns are collapsed, then all the user to expand all of them at once
# Hide a bunch of columns.
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone1"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Phone2"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Country"
And I choose "Collapse" in the open action menu
# Ensure we are ready to move onto the next step.
And I wait until "Collapsed columns 4" "button" exists
When I click on "Collapsed columns" "button"
And I click on "Select all" "option_role"
And I click on "Expand" "button" in the "form" "gradereport_grader > collapse search"
# All of the previously collapsed columns should now be visible.
Then I should see "Email" in the "First name / Last name" "table_row"
And I should see "Phone" in the "First name / Last name" "table_row"
And I should see "Mobile phone" in the "First name / Last name" "table_row"
And I should see "Country" in the "First name / Last name" "table_row"

Scenario: If multiple columns are collapsed, when selecting all and then unselecting an option, the select all is then unchecked
# Hide some columns.
Given I click on user profile field menu "Email"
And I choose "Collapse" in the open action menu
And I click on user profile field menu "Country"
And I choose "Collapse" in the open action menu
# Ensure we are ready to move onto the next step.
And I wait until "Collapsed columns 2" "button" exists
When I click on "Collapsed columns" "button"
And I click on "Select all" "option_role"
And I click on "Email" "option_role" in the "form" "gradereport_grader > collapse search"
# The select all option should now be unchecked, Checking the form or option role is iffy with behat so we use the id.
Then "input#check-all-input:not([checked=checked])" "css_element" should exist

0 comments on commit 5282ddd

Please sign in to comment.