MDL-77172 tool_capability: replace YUI search with ESM version.

This commit is contained in:
Paul Holden 2023-02-07 17:38:57 +00:00
parent 556208417d
commit 47c0e48c9c
16 changed files with 129 additions and 584 deletions

View File

@ -0,0 +1,10 @@
define("tool_capability/search",["exports","core/pending","core/utils"],(function(_exports,_pending,_utils){var obj;
/**
* Add search filtering of capabilities
*
* @module tool_capability/search
* @copyright 2023 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_pending=(obj=_pending)&&obj.__esModule?obj:{default:obj};const Selectors_capabilityOverviewForm="#capability-overview-form",Selectors_capabilitySelect='[data-search="capability"]',Selectors_capabilitySearch='[data-action="search"]';_exports.init=()=>{const capabilityOverviewForm=document.querySelector(Selectors_capabilityOverviewForm);if(!capabilityOverviewForm)return;const capabilitySelect=capabilityOverviewForm.querySelector(Selectors_capabilitySelect),capabilitySearch=capabilityOverviewForm.querySelector(Selectors_capabilitySearch),capabilitySelectFilter=searchTerm=>{const pendingPromise=new _pending.default("tool_capability/search:filter");let capabilitySelected=[];capabilitySelect.querySelectorAll("option").forEach((option=>{option.selected&&capabilitySelected.push(option.value),option.remove()}));const availableCapabilities=JSON.parse(capabilitySelect.dataset.availableCapabilities),filteredCapabilities=Object.keys(availableCapabilities).reduce(((matches,capability)=>(availableCapabilities[capability].toLowerCase().includes(searchTerm)&&(matches[capability]=availableCapabilities[capability]),matches)),[]);Object.entries(filteredCapabilities).forEach((_ref=>{let[capability,capabilityText]=_ref;const option=document.createElement("option");option.value=capability,option.innerText=capabilityText,option.selected=capabilitySelected.indexOf(capability)>-1,capabilitySelect.append(option)})),pendingPromise.resolve()},availableCapabilities={};capabilitySelect.querySelectorAll("option").forEach((option=>{availableCapabilities[option.value]=option.text})),capabilitySelect.dataset.availableCapabilities=JSON.stringify(availableCapabilities);const capabilitySearchDebounce=(0,_utils.debounce)(capabilitySelectFilter,250);capabilitySearch.addEventListener("keyup",(event=>{const pendingPromise=new _pending.default("tool_capability/search:keyup");capabilitySearchDebounce(event.target.value.toLowerCase()),setTimeout((()=>{pendingPromise.resolve()}),250)})),""!==capabilitySearch.value&&capabilitySelectFilter(capabilitySearch.value.toLowerCase())}}));
//# sourceMappingURL=search.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -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 <paulh@moodle.com>
* @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());
}
};

View File

@ -43,19 +43,22 @@ class tool_capability_settings_form extends moodleform {
$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);
@ -67,5 +70,4 @@ class tool_capability_settings_form extends moodleform {
$form->addElement('submit', 'submitbutton', get_string('getreport', 'tool_capability'));
}
}

View File

@ -55,11 +55,8 @@ $form = new tool_capability_settings_form(null, array(
'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();

View File

@ -1,3 +1,7 @@
.path-admin-tool-capability [data-search="capability"] {
min-width: 675px;
}
.path-admin-tool-capability .comparisontable {
margin-top: 150px;
}

View File

@ -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"

View File

@ -1,182 +0,0 @@
YUI.add('moodle-tool_capability-search', function (Y, NAME) {
/**
* This file contains the capability overview search functionality.
*
* @module moodle-tool_capability-search
*/
/**
* Constructs a new capability search manager.
*
* @namespace M.tool_capability
* @class Search
* @constructor
* @extends Base
*/
var SEARCH = function() {
SEARCH.superclass.constructor.apply(this, arguments);
};
SEARCH.prototype = {
/**
* The search form.
* @property form
* @type Node
* @protected
*/
form: null,
/**
* The capability select node.
* @property select
* @type Node
* @protected
*/
select: null,
/**
* An associative array of search option. Populated from the select node above during initialisation.
* @property selectoptions
* @type Object
* @protected
*/
selectoptions: {},
/**
* The search input field.
* @property input
* @type Node
* @protected
*/
input: null,
/**
* The submit button for the form.
* @property button
* @type Node
* @protected
*/
button: null,
/**
* The cancel button for the form.
* @property button
* @type Node
* @protected
*/
cancel: null,
/**
* The last search node if there is one.
* If there is a last search node then the last search term will be persisted between requests.
* @property lastsearch
* @type Node
* @protected
*/
lastsearch: null,
/**
* Constructs the search manager.
* @method initializer
*/
initializer: function() {
this.form = Y.one('#capability-overview-form');
this.select = this.form.one('select[data-search=capability]');
this.select.setStyle('minWidth', this.select.get('offsetWidth'));
this.select.get('options').each(function(option) {
var capability = option.get('value');
this.selectoptions[capability] = option;
}, this);
this.button = this.form.all('input[type=submit]');
this.lastsearch = this.form.one('input[name=search]');
var div = Y.Node.create('<div id="capabilitysearchui" class="input-group simplesearchform mb-2"' +
'data-fieldtype="text"></div>'),
label = Y.Node.create('<label for="capabilitysearch"><span class="sr-only"' +
this.get('strsearch') + '</span></label>');
this.cancel = Y.Node.create('<a class="btn btn-clear d-none icon-no-margin">' +
'<i class="icon fa fa-times fa-fw " aria-hidden="true"></i>' +
'</a>');
this.input = Y.Node.create('<input type="text" class="form-control withclear" placeholder="' +
this.get('strsearch') + '"id="capabilitysearch" />');
div.append(label).append(this.input).append(this.cancel);
this.select.insert(div, 'before');
this.input.on('keyup', this.typed, this);
this.select.on('change', this.validate, this);
this.cancel.on('click', function() {
this.input.set('value', '');
this.typed();
}, this);
if (this.lastsearch) {
this.input.set('value', this.lastsearch.get('value'));
this.typed();
if (this.select.one('option[selected]')) {
this.select.set('scrollTop', this.select.one('option[selected]').get('getX'));
}
}
this.validate();
},
/**
* Disables the submit button if there are no capabilities selected.
* @method validate
*/
validate: function() {
this.button.set('disabled', (this.select.get('value') === ''));
},
/**
* Called when ever the user types into the search field.
* This method hides any capabilities that don't match the search term.
* @method typed
*/
typed: function() {
var search = this.input.get('value'),
matching = 0,
last = null,
capability;
if (this.lastsearch) {
this.lastsearch.set('value', search);
}
this.select.all('option').remove();
for (capability in this.selectoptions) {
if (capability.indexOf(search) >= 0) {
matching++;
last = this.selectoptions[capability];
this.select.append(this.selectoptions[capability]);
}
}
if (matching === 0) {
this.input.addClass("error");
} else {
this.input.removeClass("error");
if (matching === 1) {
last.set('selected', true);
}
}
if (search !== '') {
this.cancel.removeClass("d-none");
} else {
this.cancel.addClass("d-none");
}
this.validate();
}
};
Y.extend(SEARCH, Y.Base, SEARCH.prototype, {
NAME: 'tool_capability-search',
ATTRS: {
strsearch: {}
}
});
M.tool_capability = M.tool_capability || {};
/**
* Initialises capability search functionality.
* @static
* @method M.tool_capability.init_capability_search
* @param {Object} options
*/
M.tool_capability.init_capability_search = function(options) {
new SEARCH(options);
};
}, '@VERSION@', {"requires": ["base", "node"]});

View File

@ -1 +0,0 @@
YUI.add("moodle-tool_capability-search",function(s,t){var e=function(){e.superclass.constructor.apply(this,arguments)};s.extend(e,s.Base,e.prototype={form:null,select:null,selectoptions:{},input:null,button:null,cancel:null,lastsearch:null,initializer:function(){this.form=s.one("#capability-overview-form"),this.select=this.form.one("select[data-search=capability]"),this.select.setStyle("minWidth",this.select.get("offsetWidth")),this.select.get("options").each(function(t){var e=t.get("value");this.selectoptions[e]=t},this),this.button=this.form.all("input[type=submit]"),this.lastsearch=this.form.one("input[name=search]");var t=s.Node.create('<div id="capabilitysearchui" class="input-group simplesearchform mb-2"data-fieldtype="text"></div>'),e=s.Node.create('<label for="capabilitysearch"><span class="sr-only"'+this.get("strsearch")+"</span></label>");this.cancel=s.Node.create('<a class="btn btn-clear d-none icon-no-margin"><i class="icon fa fa-times fa-fw " aria-hidden="true"></i></a>'),this.input=s.Node.create('<input type="text" class="form-control withclear" placeholder="'+this.get("strsearch")+'"id="capabilitysearch" />'),t.append(e).append(this.input).append(this.cancel),this.select.insert(t,"before"),this.input.on("keyup",this.typed,this),this.select.on("change",this.validate,this),this.cancel.on("click",function(){this.input.set("value",""),this.typed()},this),this.lastsearch&&(this.input.set("value",this.lastsearch.get("value")),this.typed(),this.select.one("option[selected]"))&&this.select.set("scrollTop",this.select.one("option[selected]").get("getX")),this.validate()},validate:function(){this.button.set("disabled",""===this.select.get("value"))},typed:function(){var t,e=this.input.get("value"),s=0,i=null;for(t in this.lastsearch&&this.lastsearch.set("value",e),this.select.all("option").remove(),this.selectoptions)0<=t.indexOf(e)&&(s++,i=this.selectoptions[t],this.select.append(this.selectoptions[t]));0===s?this.input.addClass("error"):(this.input.removeClass("error"),1===s&&i.set("selected",!0)),""!==e?this.cancel.removeClass("d-none"):this.cancel.addClass("d-none"),this.validate()}},{NAME:"tool_capability-search",ATTRS:{strsearch:{}}}),M.tool_capability=M.tool_capability||{},M.tool_capability.init_capability_search=function(t){new e(t)}},"@VERSION@",{requires:["base","node"]});

View File

@ -1,182 +0,0 @@
YUI.add('moodle-tool_capability-search', function (Y, NAME) {
/**
* This file contains the capability overview search functionality.
*
* @module moodle-tool_capability-search
*/
/**
* Constructs a new capability search manager.
*
* @namespace M.tool_capability
* @class Search
* @constructor
* @extends Base
*/
var SEARCH = function() {
SEARCH.superclass.constructor.apply(this, arguments);
};
SEARCH.prototype = {
/**
* The search form.
* @property form
* @type Node
* @protected
*/
form: null,
/**
* The capability select node.
* @property select
* @type Node
* @protected
*/
select: null,
/**
* An associative array of search option. Populated from the select node above during initialisation.
* @property selectoptions
* @type Object
* @protected
*/
selectoptions: {},
/**
* The search input field.
* @property input
* @type Node
* @protected
*/
input: null,
/**
* The submit button for the form.
* @property button
* @type Node
* @protected
*/
button: null,
/**
* The cancel button for the form.
* @property button
* @type Node
* @protected
*/
cancel: null,
/**
* The last search node if there is one.
* If there is a last search node then the last search term will be persisted between requests.
* @property lastsearch
* @type Node
* @protected
*/
lastsearch: null,
/**
* Constructs the search manager.
* @method initializer
*/
initializer: function() {
this.form = Y.one('#capability-overview-form');
this.select = this.form.one('select[data-search=capability]');
this.select.setStyle('minWidth', this.select.get('offsetWidth'));
this.select.get('options').each(function(option) {
var capability = option.get('value');
this.selectoptions[capability] = option;
}, this);
this.button = this.form.all('input[type=submit]');
this.lastsearch = this.form.one('input[name=search]');
var div = Y.Node.create('<div id="capabilitysearchui" class="input-group simplesearchform mb-2"' +
'data-fieldtype="text"></div>'),
label = Y.Node.create('<label for="capabilitysearch"><span class="sr-only"' +
this.get('strsearch') + '</span></label>');
this.cancel = Y.Node.create('<a class="btn btn-clear d-none icon-no-margin">' +
'<i class="icon fa fa-times fa-fw " aria-hidden="true"></i>' +
'</a>');
this.input = Y.Node.create('<input type="text" class="form-control withclear" placeholder="' +
this.get('strsearch') + '"id="capabilitysearch" />');
div.append(label).append(this.input).append(this.cancel);
this.select.insert(div, 'before');
this.input.on('keyup', this.typed, this);
this.select.on('change', this.validate, this);
this.cancel.on('click', function() {
this.input.set('value', '');
this.typed();
}, this);
if (this.lastsearch) {
this.input.set('value', this.lastsearch.get('value'));
this.typed();
if (this.select.one('option[selected]')) {
this.select.set('scrollTop', this.select.one('option[selected]').get('getX'));
}
}
this.validate();
},
/**
* Disables the submit button if there are no capabilities selected.
* @method validate
*/
validate: function() {
this.button.set('disabled', (this.select.get('value') === ''));
},
/**
* Called when ever the user types into the search field.
* This method hides any capabilities that don't match the search term.
* @method typed
*/
typed: function() {
var search = this.input.get('value'),
matching = 0,
last = null,
capability;
if (this.lastsearch) {
this.lastsearch.set('value', search);
}
this.select.all('option').remove();
for (capability in this.selectoptions) {
if (capability.indexOf(search) >= 0) {
matching++;
last = this.selectoptions[capability];
this.select.append(this.selectoptions[capability]);
}
}
if (matching === 0) {
this.input.addClass("error");
} else {
this.input.removeClass("error");
if (matching === 1) {
last.set('selected', true);
}
}
if (search !== '') {
this.cancel.removeClass("d-none");
} else {
this.cancel.addClass("d-none");
}
this.validate();
}
};
Y.extend(SEARCH, Y.Base, SEARCH.prototype, {
NAME: 'tool_capability-search',
ATTRS: {
strsearch: {}
}
});
M.tool_capability = M.tool_capability || {};
/**
* Initialises capability search functionality.
* @static
* @method M.tool_capability.init_capability_search
* @param {Object} options
*/
M.tool_capability.init_capability_search = function(options) {
new SEARCH(options);
};
}, '@VERSION@', {"requires": ["base", "node"]});

View File

@ -1,10 +0,0 @@
{
"name": "moodle-tool_capability-search",
"builds": {
"moodle-tool_capability-search": {
"jsfiles": [
"search.js"
]
}
}
}

View File

@ -1,177 +0,0 @@
/**
* This file contains the capability overview search functionality.
*
* @module moodle-tool_capability-search
*/
/**
* Constructs a new capability search manager.
*
* @namespace M.tool_capability
* @class Search
* @constructor
* @extends Base
*/
var SEARCH = function() {
SEARCH.superclass.constructor.apply(this, arguments);
};
SEARCH.prototype = {
/**
* The search form.
* @property form
* @type Node
* @protected
*/
form: null,
/**
* The capability select node.
* @property select
* @type Node
* @protected
*/
select: null,
/**
* An associative array of search option. Populated from the select node above during initialisation.
* @property selectoptions
* @type Object
* @protected
*/
selectoptions: {},
/**
* The search input field.
* @property input
* @type Node
* @protected
*/
input: null,
/**
* The submit button for the form.
* @property button
* @type Node
* @protected
*/
button: null,
/**
* The cancel button for the form.
* @property button
* @type Node
* @protected
*/
cancel: null,
/**
* The last search node if there is one.
* If there is a last search node then the last search term will be persisted between requests.
* @property lastsearch
* @type Node
* @protected
*/
lastsearch: null,
/**
* Constructs the search manager.
* @method initializer
*/
initializer: function() {
this.form = Y.one('#capability-overview-form');
this.select = this.form.one('select[data-search=capability]');
this.select.setStyle('minWidth', this.select.get('offsetWidth'));
this.select.get('options').each(function(option) {
var capability = option.get('value');
this.selectoptions[capability] = option;
}, this);
this.button = this.form.all('input[type=submit]');
this.lastsearch = this.form.one('input[name=search]');
var div = Y.Node.create('<div id="capabilitysearchui" class="input-group simplesearchform mb-2"' +
'data-fieldtype="text"></div>'),
label = Y.Node.create('<label for="capabilitysearch"><span class="sr-only"' +
this.get('strsearch') + '</span></label>');
this.cancel = Y.Node.create('<a class="btn btn-clear d-none icon-no-margin">' +
'<i class="icon fa fa-times fa-fw " aria-hidden="true"></i>' +
'</a>');
this.input = Y.Node.create('<input type="text" class="form-control withclear" placeholder="' +
this.get('strsearch') + '"id="capabilitysearch" />');
div.append(label).append(this.input).append(this.cancel);
this.select.insert(div, 'before');
this.input.on('keyup', this.typed, this);
this.select.on('change', this.validate, this);
this.cancel.on('click', function() {
this.input.set('value', '');
this.typed();
}, this);
if (this.lastsearch) {
this.input.set('value', this.lastsearch.get('value'));
this.typed();
if (this.select.one('option[selected]')) {
this.select.set('scrollTop', this.select.one('option[selected]').get('getX'));
}
}
this.validate();
},
/**
* Disables the submit button if there are no capabilities selected.
* @method validate
*/
validate: function() {
this.button.set('disabled', (this.select.get('value') === ''));
},
/**
* Called when ever the user types into the search field.
* This method hides any capabilities that don't match the search term.
* @method typed
*/
typed: function() {
var search = this.input.get('value'),
matching = 0,
last = null,
capability;
if (this.lastsearch) {
this.lastsearch.set('value', search);
}
this.select.all('option').remove();
for (capability in this.selectoptions) {
if (capability.indexOf(search) >= 0) {
matching++;
last = this.selectoptions[capability];
this.select.append(this.selectoptions[capability]);
}
}
if (matching === 0) {
this.input.addClass("error");
} else {
this.input.removeClass("error");
if (matching === 1) {
last.set('selected', true);
}
}
if (search !== '') {
this.cancel.removeClass("d-none");
} else {
this.cancel.addClass("d-none");
}
this.validate();
}
};
Y.extend(SEARCH, Y.Base, SEARCH.prototype, {
NAME: 'tool_capability-search',
ATTRS: {
strsearch: {}
}
});
M.tool_capability = M.tool_capability || {};
/**
* Initialises capability search functionality.
* @static
* @method M.tool_capability.init_capability_search
* @param {Object} options
*/
M.tool_capability.init_capability_search = function(options) {
new SEARCH(options);
};

View File

@ -1,8 +0,0 @@
{
"moodle-tool_capability-search": {
"requires": [
"base",
"node"
]
}
}

View File

@ -58,10 +58,6 @@
display: none;
}
#page-admin-report-capability-index #capabilitysearch {
width: 30em;
}
#page-admin-qtypes #qtypes div,
#page-admin-qtypes #qtypes form,
#page-admin-qbehaviours #qbehaviours div,

View File

@ -12635,9 +12635,6 @@ blockquote {
.timewarninghidden {
display: none; }
#page-admin-report-capability-index #capabilitysearch {
width: 30em; }
#page-admin-qtypes #qtypes div,
#page-admin-qtypes #qtypes form,
#page-admin-qbehaviours #qbehaviours div,

View File

@ -12635,9 +12635,6 @@ blockquote {
.timewarninghidden {
display: none; }
#page-admin-report-capability-index #capabilitysearch {
width: 30em; }
#page-admin-qtypes #qtypes div,
#page-admin-qtypes #qtypes form,
#page-admin-qbehaviours #qbehaviours div,