Skip to content

Commit

Permalink
MDL-77172 tool_capability: replace YUI search with ESM version.
Browse files Browse the repository at this point in the history
  • Loading branch information
paulholden committed Mar 4, 2023
1 parent 5562084 commit 47c0e48
Show file tree
Hide file tree
Showing 16 changed files with 129 additions and 584 deletions.
10 changes: 10 additions & 0 deletions admin/tool/capability/amd/build/search.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions admin/tool/capability/amd/build/search.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 102 additions & 0 deletions admin/tool/capability/amd/src/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// 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 <http://www.gnu.org/licenses/>.

/**
* Add search filtering of capabilities
*
* @module tool_capability/search
* @copyright 2023 Paul Holden <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

import Pending from 'core/pending';
import {debounce} from 'core/utils';

const Selectors = {
capabilityOverviewForm: '#capability-overview-form',
capabilitySelect: '[data-search="capability"]',
capabilitySearch: '[data-action="search"]',
};

const debounceTimer = 250;

/**
* Initialize module
*/
export const init = () => {
const capabilityOverviewForm = document.querySelector(Selectors.capabilityOverviewForm);
if (!capabilityOverviewForm) {
return;
}

const capabilitySelect = capabilityOverviewForm.querySelector(Selectors.capabilitySelect);
const capabilitySearch = capabilityOverviewForm.querySelector(Selectors.capabilitySearch);

const capabilitySelectFilter = searchTerm => {
const pendingPromise = new Pending('tool_capability/search:filter');

// Remove existing options, remembering which were previously selected.
let capabilitySelected = [];
capabilitySelect.querySelectorAll('option').forEach(option => {
if (option.selected) {
capabilitySelected.push(option.value);
}
option.remove();
});

// Filter for matching capabilities.
const availableCapabilities = JSON.parse(capabilitySelect.dataset.availableCapabilities);
const filteredCapabilities = Object.keys(availableCapabilities).reduce((matches, capability) => {
if (availableCapabilities[capability].toLowerCase().includes(searchTerm)) {
matches[capability] = availableCapabilities[capability];
}
return matches;
}, []);

// Re-create filtered options.
Object.entries(filteredCapabilities).forEach(([capability, capabilityText]) => {
const option = document.createElement('option');
option.value = capability;
option.innerText = capabilityText;
option.selected = capabilitySelected.indexOf(capability) > -1;
capabilitySelect.append(option);
});

pendingPromise.resolve();
};

// Cache initial capability options.
const availableCapabilities = {};
capabilitySelect.querySelectorAll('option').forEach(option => {
availableCapabilities[option.value] = option.text;
});
capabilitySelect.dataset.availableCapabilities = JSON.stringify(availableCapabilities);

// Debounce the event listener on the search element to allow user to finish typing.
const capabilitySearchDebounce = debounce(capabilitySelectFilter, debounceTimer);
capabilitySearch.addEventListener('keyup', event => {
const pendingPromise = new Pending('tool_capability/search:keyup');

capabilitySearchDebounce(event.target.value.toLowerCase());
setTimeout(() => {
pendingPromise.resolve();
}, debounceTimer);
});

// Ensure filter is applied on form load.
if (capabilitySearch.value !== '') {
capabilitySelectFilter(capabilitySearch.value.toLowerCase());
}
};
10 changes: 6 additions & 4 deletions admin/tool/capability/classes/settings_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,22 @@ public function definition() {
$form = $this->_form;
$capabilities = $this->_customdata['capabilities'];
$roles = $this->_customdata['roles'];

// Set the form ID.
$form->setAttributes(array('id' => 'capability-overview-form') + $form->getAttributes());

$form->addElement('header', 'reportsettings', get_string('reportsettings', 'tool_capability'));
$form->addElement('html', html_writer::tag('p', get_string('intro', 'tool_capability'), array('id' => 'intro')));

$form->addElement('hidden', 'search');
$form->setType('search', PARAM_TEXT);

$attributes = array('multiple' => 'multiple', 'size' => 10, 'data-search' => 'capability');
$form->addElement('select', 'capability', get_string('capabilitylabel', 'tool_capability'), $capabilities, $attributes);
$form->setType('capability', PARAM_CAPABILITY);

$strsearch = get_string('search');
$form->addElement('text', 'search', $strsearch, ['data-action' => 'search', 'placeholder' => $strsearch])
->setHiddenLabel(true);
$form->setType('search', PARAM_TEXT);

$attributes = array('multiple' => 'multiple', 'size' => 10);
$form->addElement('select', 'roles', get_string('roleslabel', 'tool_capability'), $roles, $attributes);
$form->setType('roles', PARAM_TEXT);
Expand All @@ -67,5 +70,4 @@ public function definition() {

$form->addElement('submit', 'submitbutton', get_string('getreport', 'tool_capability'));
}

}
7 changes: 2 additions & 5 deletions admin/tool/capability/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,8 @@
'capabilities' => $capabilitychoices,
'roles' => $rolechoices
));
$PAGE->requires->yui_module(
'moodle-tool_capability-search',
'M.tool_capability.init_capability_search',
array(array('strsearch' => get_string('search')))
);

$PAGE->requires->js_call_amd('tool_capability/search', 'init');

// Log.
$capabilities = array();
Expand Down
4 changes: 4 additions & 0 deletions admin/tool/capability/styles.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.path-admin-tool-capability [data-search="capability"] {
min-width: 675px;
}

.path-admin-tool-capability .comparisontable {
margin-top: 150px;
}
Expand Down
9 changes: 4 additions & 5 deletions admin/tool/capability/tests/behat/show_capabilies.feature
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,18 @@ Feature: show capabilities for selected roles
Scenario: filter capability list using javascript
Given I should see "moodle/site:config" in the "Capability" "field"
And I should see "moodle/course:change" in the "Capability" "field"
When I wait until the page is ready
And I set the field "capabilitysearch" to "moodle/course:change"
And I set the field "Search" in the "#capability-overview-form" "css_element" to "moodle/course:change"
Then I should see "moodle/course:change" in the "Capability" "field"
And I should not see "moodle/site:config" in the "Capability" "field"

@javascript
Scenario: selecting capabilities using filters
Given I should see "moodle/course:change" in the "Capability" "field"
When I wait until the page is ready
And I set the field "capabilitysearch" to "moodle/course:change"
And I set the field "Search" in the "#capability-overview-form" "css_element" to "moodle/course:change"
And I wait "1" seconds
When I set the following fields to these values:
| Capability: | moodle/course:changecategory |
| Roles: | Student |
And I set the field "capabilitysearch" to ""
And I click on "Get the overview" "button"
Then I should see "moodle/course:changecategory" in the "comparisontable" "table"
And the field "Capability:" matches value "moodle/course:changecategory"
Loading

0 comments on commit 47c0e48

Please sign in to comment.