Merge branch 'MDL-70632-311' of git://github.com/paulholden/moodle into MOODLE_311_STABLE

This commit is contained in:
Andrew Nicols
2021-02-04 09:26:40 +08:00
7 changed files with 131 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
define ("tool_langimport/search",["exports","core/pending","core/utils"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);function d(a,b){return j(a)||h(a,b)||f(a,b)||e()}function e(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function f(a,b){if(!a)return;if("string"==typeof a)return g(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return g(a,b)}function g(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c<b;c++){d[c]=a[c]}return d}function h(a,b){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(a)))return;var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function j(a){if(Array.isArray(a))return a}var k={AVAILABLE_LANG_SELECT:"select",AVAILABLE_LANG_SEARCH:"[data-action=\"search\"]"},l=250;a.default={init:function init(a){var e=a.querySelector(k.AVAILABLE_LANG_SELECT),f=function(a){var c=new b.default("tool_langimport/search:filter");e.querySelectorAll("option").forEach(function(a){a.remove()});var f=a.target.value.toLowerCase(),g=JSON.parse(e.dataset.availableLanguages),h=Object.keys(g).reduce(function(a,b){if(g[b].toLowerCase().includes(f)){a[b]=g[b]}return a},[]);Object.entries(h).forEach(function(a){var b=d(a,2),c=b[0],f=b[1],g=document.createElement("option");g.value=c;g.innerText=f;e.append(g)});c.resolve()},g={};e.querySelectorAll("option").forEach(function(a){g[a.value]=a.text});e.dataset.availableLanguages=JSON.stringify(g);var h=a.querySelector(k.AVAILABLE_LANG_SEARCH);h.addEventListener("keydown",function(a){if("Enter"===a.key){a.preventDefault()}});h.addEventListener("keyup",function(a){var d=new b.default("tool_langimport/search:keyup");(0,c.debounce)(f,l)(a);setTimeout(function(){d.resolve()},l)})}};return a.default});
//# sourceMappingURL=search.min.js.map
File diff suppressed because one or more lines are too long
+100
View File
@@ -0,0 +1,100 @@
// 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 available language packs
*
* @module tool_langimport/search
* @package tool_langimport
* @copyright 2021 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 = {
AVAILABLE_LANG_SELECT: 'select',
AVAILABLE_LANG_SEARCH: '[data-action="search"]',
};
const DEBOUNCE_TIMER = 250;
/**
* Initialize module
*
* @param {Element} form
*/
const init = (form) => {
const availableLangsElement = form.querySelector(SELECTORS.AVAILABLE_LANG_SELECT);
const availableLangsFilter = (event) => {
const pendingPromise = new Pending('tool_langimport/search:filter');
// Remove existing options.
availableLangsElement.querySelectorAll('option').forEach((option) => {
option.remove();
});
// Filter for matching languages.
const searchTerm = event.target.value.toLowerCase();
const availableLanguages = JSON.parse(availableLangsElement.dataset.availableLanguages);
const filteredLanguages = Object.keys(availableLanguages).reduce((matches, langcode) => {
if (availableLanguages[langcode].toLowerCase().includes(searchTerm)) {
matches[langcode] = availableLanguages[langcode];
}
return matches;
}, []);
// Re-create filtered options.
Object.entries(filteredLanguages).forEach(([langcode, langname]) => {
const option = document.createElement('option');
option.value = langcode;
option.innerText = langname;
availableLangsElement.append(option);
});
pendingPromise.resolve();
};
// Cache initial available language options.
const availableLanguages = {};
availableLangsElement.querySelectorAll('option').forEach((option) => {
availableLanguages[option.value] = option.text;
});
availableLangsElement.dataset.availableLanguages = JSON.stringify(availableLanguages);
// Register event listeners on the search element.
const availableLangsSearch = form.querySelector(SELECTORS.AVAILABLE_LANG_SEARCH);
availableLangsSearch.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
event.preventDefault();
}
});
// Debounce the event listener to allow the user to finish typing.
availableLangsSearch.addEventListener('keyup', (event) => {
const pendingPromise = new Pending('tool_langimport/search:keyup');
debounce(availableLangsFilter, DEBOUNCE_TIMER)(event);
setTimeout(() => {
pendingPromise.resolve();
}, DEBOUNCE_TIMER);
});
};
export default {
init: init,
};
@@ -45,6 +45,7 @@ $string['noenglishuninstall'] = 'The English language pack cannot be uninstalled
$string['nolangupdateneeded'] = 'All your language packs are up to date, no update is needed';
$string['pluginname'] = 'Language packs';
$string['purgestringcaches'] = 'Purge string caches';
$string['search'] = 'Search available language packs';
$string['selectlangs'] = 'Select languages to uninstall';
$string['uninstall'] = 'Uninstall selected language pack(s)';
$string['uninstallconfirm'] = 'You are about to completely uninstall these language packs: <strong>{$a}</strong>. Are you sure?';
+5
View File
@@ -3,3 +3,8 @@
float: none;
width: 100%;
}
#page-admin-tool-langimport-index #menuuninstalllang,
#page-admin-tool-langimport-index #menupack {
height: 300px;
}
@@ -105,6 +105,13 @@
{{/toinstalloptions}}
</select>
</div>
<div class="mb-3">
{{< core/search_input_auto }}
{{$label}}
{{#str}} search, tool_langimport {{/str}}
{{/label}}
{{/ core/search_input_auto }}
</div>
<div class="form-group">
<input type="hidden" name="sesskey" value="{{sesskey}}">
<input type="submit" value="{{#str}}install, tool_langimport{{/str}}" class="btn btn-secondary">
@@ -115,3 +122,8 @@
{{/caninstall}}
</div>
</div>
{{#js}}
require(['tool_langimport/search'], function(search) {
search.init(document.querySelector('#installform'));
});
{{/js}}
@@ -20,6 +20,16 @@ Feature: Manage language packs
And I should see "The language pack 'en_ar' was installed."
And I log out
@javascript
Scenario: Search for available language pack
Given I log in as "admin"
And I navigate to "Language > Language packs" in site administration
When I set the field "Search available language packs" to "pirate"
Then the "Available language packs" select box should not contain "es"
And I set the field "Available language packs" to "en_ar"
And I press "Install selected language pack(s)"
And I should see "Language pack 'en_ar' was successfully installed"
Scenario: Update language pack
Given outdated langpack 'en_ar' is installed
And I log in as "admin"