Merge pull request #2759 from limonspb/presets_remove_description

Presets: shorter index.json file, added option groups, preset priority, updated search, source versioning
10.8-maintenance
haslinghuis 2022-01-18 00:36:01 +01:00 committed by GitHub
commit 598ab9b544
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 353 additions and 123 deletions

View File

@ -6379,9 +6379,13 @@
"message": "Do you really want to close the configurator?" "message": "Do you really want to close the configurator?"
}, },
"dropDownSelectAll": { "dropDownSelectAll": {
"message": "[Select all]", "message": "[Select/deselect all]",
"description": "Select all item in the drop down/multiple select" "description": "Select all item in the drop down/multiple select"
}, },
"dropDownFilterDisabled": {
"message": "Select...",
"description": "Text indicating nothing is selected in the drop down/multiple select (filter disabled)"
},
"dropDownAll": { "dropDownAll": {
"message": "All", "message": "All",
"description": "Text indicating everything is selected in the drop down/multiple select" "description": "Text indicating everything is selected in the drop down/multiple select"
@ -6577,5 +6581,13 @@
"presetsTooManyPresetsFound": { "presetsTooManyPresetsFound": {
"message": "Reached the maximum limit of the shown presets number", "message": "Reached the maximum limit of the shown presets number",
"description": "Message that apprears on presets tab if too many presets found" "description": "Message that apprears on presets tab if too many presets found"
},
"presetsOptionsPlaceholder": {
"message": "ATTENTION! Review the list of options",
"description": "Placeholder for the options list dropdown"
},
"presetsVersionMismatch": {
"message": "Preset source version mismatch.<br/>Required version: {{versionRequired}}<br/>Preset source version: {{versionSource}}<br/>Using this preset source could be dangerous.<br/>Do you want to continue?",
"description": "Placeholder for the options list dropdown"
} }
} }

View File

@ -137,6 +137,7 @@
<script type="text/javascript" src="./tabs/presets/PickedPreset.js"></script> <script type="text/javascript" src="./tabs/presets/PickedPreset.js"></script>
<script type="text/javascript" src="./tabs/presets/DetailedDialog/PresetsDetailedDialog.js"></script> <script type="text/javascript" src="./tabs/presets/DetailedDialog/PresetsDetailedDialog.js"></script>
<script type="text/javascript" src="./tabs/presets/TitlePanel/PresetTitlePanel.js"></script> <script type="text/javascript" src="./tabs/presets/TitlePanel/PresetTitlePanel.js"></script>
<script type="text/javascript" src="./tabs/presets/PresetsRepoIndexed/PresetParser.js"></script>
<script type="text/javascript" src="./tabs/presets/PresetsRepoIndexed/PresetsRepoIndexed.js"></script> <script type="text/javascript" src="./tabs/presets/PresetsRepoIndexed/PresetsRepoIndexed.js"></script>
<script type="text/javascript" src="./tabs/presets/PresetsRepoIndexed/PresetsGithubRepo.js"></script> <script type="text/javascript" src="./tabs/presets/PresetsRepoIndexed/PresetsGithubRepo.js"></script>
<script type="text/javascript" src="./tabs/presets/PresetsRepoIndexed/PresetsWebsiteRepo.js"></script> <script type="text/javascript" src="./tabs/presets/PresetsRepoIndexed/PresetsWebsiteRepo.js"></script>

View File

@ -46,6 +46,11 @@
padding-left: 20px; padding-left: 20px;
} }
#presets_options_panel .ms-choice {
border-color: var(--accentBorder);
border-width: 2px;
}
#presets_detailed_dialog_loading { #presets_detailed_dialog_loading {
height: 300px; height: 300px;
} }

View File

@ -125,24 +125,59 @@ class PresetsDetailedDialog {
_createOptionsSelect(options) { _createOptionsSelect(options) {
options.forEach(option => { options.forEach(option => {
let selectedString = "selected=\"selected\""; if (!option.childs) {
if (!option.checked) { this._addOption(this._domOptionsSelect, option, false);
selectedString = ""; } else {
this._addOptionGroup(this._domOptionsSelect, option);
} }
this._domOptionsSelect.append(`<option value="${option.name}" ${selectedString}>${option.name}</option>`);
}); });
this._domOptionsSelect.multipleSelect({ this._domOptionsSelect.multipleSelect({
placeholder: i18n.getMessage("dropDownAll"), placeholder: i18n.getMessage("presetsOptionsPlaceholder"),
formatSelectAll () { return i18n.getMessage("dropDownSelectAll"); }, formatSelectAll () { return i18n.getMessage("dropDownSelectAll"); },
formatAllSelected() { return i18n.getMessage("dropDownAll"); }, formatAllSelected() { return i18n.getMessage("dropDownAll"); },
onClick: () => this._optionsSelectionChanged(), onClick: () => this._optionsSelectionChanged(),
onCheckAll: () => this._optionsSelectionChanged(), onCheckAll: () => this._optionsSelectionChanged(),
onUncheckAll: () => this._optionsSelectionChanged(), onUncheckAll: () => this._optionsSelectionChanged(),
hideOptgroupCheckboxes: true,
singleRadio: true,
selectAll: false,
styler: function (row) {
let style = "";
if (row.type === 'optgroup') {
style = 'font-weight: bold;';
} else if (row.classes.includes("optionHasParent")) {
style = 'padding-left: 22px;';
}
return style;
},
}); });
} }
_addOptionGroup(parentElement, optionGroup) {
const optionGroupElement = $(`<optgroup label="${optionGroup.name}"></optgroup>`);
optionGroup.childs.forEach(option => {
this._addOption(optionGroupElement, option, true);
});
parentElement.append(optionGroupElement);
}
_addOption(parentElement, option, hasParent) {
let selectedString = "selected=\"selected\"";
if (!option.checked) {
selectedString = "";
}
let classString = "";
if (hasParent) {
classString = "class=\"optionHasParent\"";
}
parentElement.append(`<option value="${option.name}" ${selectedString} ${classString}>${option.name}</option>`);
}
_optionsSelectionChanged() { _optionsSelectionChanged() {
this._updateFinalCliText(); this._updateFinalCliText();
} }

View File

@ -0,0 +1,224 @@
'use strict';
class PresetParser {
constructor(settings) {
this._settings = settings;
}
readPresetProperties(preset, strings) {
const propertiesToRead = ["description", "discussion", "warning", "disclaimer", "include_warning", "include_disclaimer", "discussion"];
const propertiesMetadata = {};
preset.options = [];
propertiesToRead.forEach(propertyName => {
// metadata of each property, name, type, optional true/false; example:
// keywords: {type: MetadataTypes.WORDS_ARRAY, optional: true}
propertiesMetadata[propertyName] = this._settings.presetsFileMetadata[propertyName];
preset[propertyName] = undefined;
});
preset._currentOptionGroup = undefined;
for (const line of strings) {
if (line.startsWith(this._settings.MetapropertyDirective)) {
this._parseAttributeLine(preset, line, propertiesMetadata);
}
}
delete preset._currentOptionGroup;
}
_parseAttributeLine(preset, line, propertiesMetadata) {
line = line.slice(this._settings.MetapropertyDirective.length).trim(); // (#$ DESCRIPTION: foo) -> (DESCRIPTION: foo)
const lowCaseLine = line.toLowerCase();
let isProperty = false;
for (const propertyName in propertiesMetadata) {
const lineBeginning = `${propertyName.toLowerCase()}:`; // "description:"
if (lowCaseLine.startsWith(lineBeginning)) {
line = line.slice(lineBeginning.length).trim(); // (Title: foo) -> (foo)
this._parseProperty(preset, line, propertyName);
isProperty = true;
}
}
if (!isProperty && lowCaseLine.startsWith(this._settings.OptionsDirectives.OPTION_DIRECTIVE)) {
this._parseOptionDirective(preset, line);
}
}
_parseOptionDirective(preset, line) {
const lowCaseLine = line.toLowerCase();
if (lowCaseLine.startsWith(this._settings.OptionsDirectives.BEGIN_OPTION_DIRECTIVE)) {
const option = this._getOption(line);
if (!preset._currentOptionGroup) {
preset.options.push(option);
} else {
preset._currentOptionGroup.childs.push(option);
}
} else if (lowCaseLine.startsWith(this._settings.OptionsDirectives.BEGIN_OPTION_GROUP_DIRECTIVE)) {
const optionGroup = this._getOptionGroup(line);
preset._currentOptionGroup = optionGroup;
preset.options.push(optionGroup);
} else if (lowCaseLine.startsWith(this._settings.OptionsDirectives.END_OPTION_GROUP_DIRECTIVE)) {
preset._currentOptionGroup = undefined;
}
}
_getOption(line) {
const directiveRemoved = line.slice(this._settings.OptionsDirectives.BEGIN_OPTION_DIRECTIVE.length).trim();
const directiveRemovedLowCase = directiveRemoved.toLowerCase();
const OptionChecked = this._isOptionChecked(directiveRemovedLowCase);
const regExpRemoveChecked = new RegExp(this._escapeRegex(this._settings.OptionsDirectives.OPTION_CHECKED), 'gi');
const regExpRemoveUnchecked = new RegExp(this._escapeRegex(this._settings.OptionsDirectives.OPTION_UNCHECKED), 'gi');
let optionName = directiveRemoved.replace(regExpRemoveChecked, "");
optionName = optionName.replace(regExpRemoveUnchecked, "").trim();
return {
name: optionName.slice(1).trim(),
checked: OptionChecked,
};
}
_getOptionGroup(line) {
const directiveRemoved = line.slice(this._settings.OptionsDirectives.BEGIN_OPTION_GROUP_DIRECTIVE.length).trim();
return {
name: directiveRemoved.slice(1).trim(),
childs: [],
};
}
_isOptionChecked(lowCaseLine) {
return lowCaseLine.includes(this._settings.OptionsDirectives.OPTION_CHECKED);
}
_parseProperty(preset, line, propertyName) {
switch(this._settings.presetsFileMetadata[propertyName].type) {
case this._settings.MetadataTypes.STRING_ARRAY:
this._processArrayProperty(preset, line, propertyName);
break;
case this._settings.MetadataTypes.STRING:
this._processStringProperty(preset, line, propertyName);
break;
case this._settings.MetadataTypes.FILE_PATH:
this._processStringProperty(preset, line, propertyName);
break;
case this._settings.MetadataTypes.FILE_PATH_ARRAY:
this._processArrayProperty(preset, line, propertyName);
break;
default:
this.console.err(`Parcing preset: unknown property type '${this._settings.presetsFileMetadata[property].type}' for the property '${propertyName}'`);
}
}
_processArrayProperty(preset, line, propertyName) {
if (!preset[propertyName]) {
preset[propertyName] = [];
}
preset[propertyName].push(line);
}
_processStringProperty(preset, line, propertyName) {
preset[propertyName] = line;
}
_getOptionName(line) {
const directiveRemoved = line.slice(this._settings.OptionsDirectives.BEGIN_OPTION_DIRECTIVE.length).trim();
const regExpRemoveChecked = new RegExp(this._escapeRegex(this._settings.OptionsDirectives.OPTION_CHECKED +":"), 'gi');
const regExpRemoveUnchecked = new RegExp(this._escapeRegex(this._settings.OptionsDirectives.OPTION_UNCHECKED +":"), 'gi');
let optionName = directiveRemoved.replace(regExpRemoveChecked, "");
optionName = optionName.replace(regExpRemoveUnchecked, "").trim();
return optionName;
}
_escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
removeUncheckedOptions(strings, checkedOptions) {
let resultStrings = [];
let isCurrentOptionExcluded = false;
const lowerCasedCheckedOptions = checkedOptions.map(optionName => optionName.toLowerCase());
strings.forEach(str => {
if (this._isLineAttribute(str)) {
const line = this._removeAttributeDirective(str);
if (this._isOptionBegin(line)) {
const optionNameLowCase = this._getOptionName(line).toLowerCase();
if (!lowerCasedCheckedOptions.includes(optionNameLowCase)) {
isCurrentOptionExcluded = true;
}
} else if (this._isOptionEnd(line)) {
isCurrentOptionExcluded = false;
}
} else if (!isCurrentOptionExcluded) {
resultStrings.push(str);
}
});
resultStrings = this._removeExcessiveEmptyLines(resultStrings);
return resultStrings;
}
_removeExcessiveEmptyLines(strings) {
// removes empty lines if there are two or more in a row leaving just one empty line
const result = [];
let lastStringEmpty = false;
strings.forEach(str => {
if ("" !== str || !lastStringEmpty) {
result.push(str);
}
if ("" === str) {
lastStringEmpty = true;
} else {
lastStringEmpty = false;
}
});
return result;
}
_isLineAttribute(line) {
return line.trim().startsWith(this._settings.MetapropertyDirective);
}
_isOptionBegin(line) {
const lowCaseLine = line.toLowerCase();
return lowCaseLine.startsWith(this._settings.OptionsDirectives.BEGIN_OPTION_DIRECTIVE);
}
_isOptionEnd(line) {
const lowCaseLine = line.toLowerCase();
return lowCaseLine.startsWith(this._settings.OptionsDirectives.END_OPTION_DIRECTIVE);
}
_removeAttributeDirective(line) {
return line.trim().slice(this._settings.MetapropertyDirective.length).trim();
}
isIncludeFound(strings) {
for (const str of strings) {
const match = PresetParser._sRegExpInclude.exec(str);
if (match !== null) {
return true;
}
}
return false;
}
}
// Reg exp extracts file/path.txt from # include: file/path.txt
PresetParser._sRegExpInclude = /^#\$[ ]+?INCLUDE:[ ]+?(?<filePath>\S+$)/;

View File

@ -14,96 +14,25 @@ class PresetsRepoIndexed {
loadIndex() { loadIndex() {
return fetch(this._urlRaw + "index.json", {cache: "no-cache"}) return fetch(this._urlRaw + "index.json", {cache: "no-cache"})
.then(res => res.json()) .then(res => res.json())
.then(out => this._index = out); .then(out => {
} this._index = out;
this._settings = this._index.settings;
removeUncheckedOptions(strings, checkedOptions) { this._PresetParser = new PresetParser(this._index.settings);
let resultStrings = []; });
let isCurrentOptionExcluded = false;
const lowerCasedCheckedOptions = checkedOptions.map(optionName => optionName.toLowerCase());
strings.forEach(str => {
if (this._isLineAttribute(str)) {
const line = this._removeAttributeDirective(str);
if (this._isOptionBegin(line)) {
const optionNameLowCase = this._getOptionName(line).toLowerCase();
if (!lowerCasedCheckedOptions.includes(optionNameLowCase)) {
isCurrentOptionExcluded = true;
}
} else if (this._isOptionEnd(line)) {
isCurrentOptionExcluded = false;
}
} else if (!isCurrentOptionExcluded) {
resultStrings.push(str);
}
});
resultStrings = this._removeExcessiveEmptyLines(resultStrings);
return resultStrings;
}
_removeExcessiveEmptyLines(strings) {
// removes empty lines if there are two or more in a row leaving just one empty line
const result = [];
let lastStringEmpty = false;
strings.forEach(str => {
if ("" !== str || !lastStringEmpty) {
result.push(str);
}
if ("" === str) {
lastStringEmpty = true;
} else {
lastStringEmpty = false;
}
});
return result;
}
_isLineAttribute(line) {
return line.trim().startsWith(PresetsRepoIndexed._sCliAttributeDirective);
}
_isOptionBegin(line) {
const lowCaseLine = line.toLowerCase();
return lowCaseLine.startsWith(this._index.settings.OptionsDirectives.BEGIN_OPTION_DIRECTIVE);
}
_isOptionEnd(line) {
const lowCaseLine = line.toLowerCase();
return lowCaseLine.startsWith(this._index.settings.OptionsDirectives.END_OPTION_DIRECTIVE);
}
_getOptionName(line) {
const directiveRemoved = line.slice(this._index.settings.OptionsDirectives.BEGIN_OPTION_DIRECTIVE.length).trim();
const regExpRemoveChecked = new RegExp(this._escapeRegex(this._index.settings.OptionsDirectives.OPTION_CHECKED +":"), 'gi');
const regExpRemoveUnchecked = new RegExp(this._escapeRegex(this._index.settings.OptionsDirectives.OPTION_UNCHECKED +":"), 'gi');
let optionName = directiveRemoved.replace(regExpRemoveChecked, "");
optionName = optionName.replace(regExpRemoveUnchecked, "").trim();
return optionName;
}
_escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
_removeAttributeDirective(line) {
return line.trim().slice(PresetsRepoIndexed._sCliAttributeDirective.length).trim();
} }
getPresetOnlineLink(preset) { getPresetOnlineLink(preset) {
return this._urlViewOnline + preset.fullPath; return this._urlViewOnline + preset.fullPath;
} }
removeUncheckedOptions(strings, checkedOptions) {
return this._PresetParser.removeUncheckedOptions(strings, checkedOptions);
}
_parceInclude(strings, includeRowIndexes, promises) _parceInclude(strings, includeRowIndexes, promises)
{ {
for (let i = 0; i < strings.length; i++) { for (let i = 0; i < strings.length; i++) {
const match = PresetsRepoIndexed._sRegExpInclude.exec(strings[i]); const match = PresetParser._sRegExpInclude.exec(strings[i]);
if (match !== null) { if (match !== null) {
includeRowIndexes.push(i); includeRowIndexes.push(i);
@ -131,7 +60,7 @@ class PresetsRepoIndexed {
} }
_executeIncludeNested(strings) { _executeIncludeNested(strings) {
const isIncludeFound = this._isIncludeFound(strings); const isIncludeFound = this._PresetParser.isIncludeFound(strings);
if (isIncludeFound) { if (isIncludeFound) {
return this._executeIncludeOnce(strings) return this._executeIncludeOnce(strings)
@ -141,18 +70,6 @@ class PresetsRepoIndexed {
} }
} }
_isIncludeFound(strings) {
for (const str of strings) {
const match = PresetsRepoIndexed._sRegExpInclude.exec(str);
if (match !== null) {
return true;
}
}
return false;
}
loadPreset(preset) { loadPreset(preset) {
const promiseMainText = this._loadPresetText(this._urlRaw + preset.fullPath); const promiseMainText = this._loadPresetText(this._urlRaw + preset.fullPath);
@ -160,6 +77,7 @@ class PresetsRepoIndexed {
.then(text => { .then(text => {
let strings = text.split("\n"); let strings = text.split("\n");
strings = strings.map(str => str.trim()); strings = strings.map(str => str.trim());
this._PresetParser.readPresetProperties(preset, strings);
return strings; return strings;
}) })
.then(strings => this._executeIncludeNested(strings)) .then(strings => this._executeIncludeNested(strings))
@ -215,9 +133,3 @@ class PresetsRepoIndexed {
}); });
} }
} }
PresetsRepoIndexed._sCliCommentDirective = "#";
PresetsRepoIndexed._sCliAttributeDirective = "#$";
// Reg exp extracts file/path.txt from # include: file/path.txt
PresetsRepoIndexed._sRegExpInclude = /^#\$[ ]+?INCLUDE:[ ]+?(?<filePath>\S+$)/;

View File

@ -287,11 +287,25 @@
} }
/* hack-fix for multiple-select with small font size. Originally checkboxes are not ligned with the text options when the font size is smaller than 0.7em */ /* hack-fix for multiple-select with small font size. Originally checkboxes are not ligned with the text options when the font size is smaller than 0.7em */
.tab-presets .tab-presets .ms-drop input[type="radio"], .ms-drop input[type="checkbox"] {
.ms-drop input[type="radio"], .ms-drop input[type="checkbox"] {
margin-top: 0.1rem !important; margin-top: 0.1rem !important;
} }
/* hack-fix for multiple-select. Places "X" button vertically in the middle for the current font. "X" icon clears the current selection. */
.tab-presets .ms-choice>div.icon-close {
padding-top: 3px;
}
/* hack-fix for multiple-select. Prevents "X" button from changing color on hover. "X" icon clears the current selection */
.tab-presets .ms-choice > div.icon-close:hover::before {
color: rgb(136, 136, 136);
}
/* hack-fix for multiple-select. Makes "X" button bigger. "X" icon clears the current selection */
.tab-presets .ms-choice>div.icon-close {
font-size: 16px;
}
.presets_filter_table_wrapper { .presets_filter_table_wrapper {
display: grid; display: grid;
grid-gap: 5px; grid-gap: 5px;

View File

@ -4,6 +4,7 @@ TABS.presets = {
presetsRepo: null, presetsRepo: null,
cliEngine: null, cliEngine: null,
pickedPresetList: [], pickedPresetList: [],
majorVersion: 1,
}; };
TABS.presets.initialize = function (callback) { TABS.presets.initialize = function (callback) {
@ -292,7 +293,9 @@ TABS.presets.tryLoadPresets = function() {
this._divGlobalLoading.toggle(true); this._divGlobalLoading.toggle(true);
this._domWarningNotOfficialSource.toggle(!this.presetsSourcesDialog.isOfficialActive); this._domWarningNotOfficialSource.toggle(!this.presetsSourcesDialog.isOfficialActive);
this.presetsRepo.loadIndex().then(() => { this.presetsRepo.loadIndex()
.then(() => this.checkPresetSourceVersion())
.then(() => {
this.prepareFilterFields(); this.prepareFilterFields();
this._divGlobalLoading.toggle(false); this._divGlobalLoading.toggle(false);
this._divMainContent.toggle(true); this._divMainContent.toggle(true);
@ -303,13 +306,35 @@ TABS.presets.tryLoadPresets = function() {
}); });
}; };
TABS.presets.checkPresetSourceVersion = function() {
return new Promise((resolve, reject) => {
if (this.majorVersion === this.presetsRepo.index.majorVersion) {
resolve();
} else {
const versionRequired = `${this.majorVersion}.X`;
const versionSource = `${this.presetsRepo.index.majorVersion}.${this.presetsRepo.index.minorVersion}`;
const dialogSettings = {
title: i18n.getMessage("presetsWarningDialogTitle"),
text: i18n.getMessage("presetsVersionMismatch", {"versionRequired": versionRequired, "versionSource":versionSource}),
buttonYesText: i18n.getMessage("yes"),
buttonNoText: i18n.getMessage("no"),
buttonYesCallback: () => resolve(),
buttonNoCallback: () => reject("Prset source version mismatch"),
};
GUI.showYesNoDialog(dialogSettings);
}
});
};
TABS.presets.prepareFilterFields = function() { TABS.presets.prepareFilterFields = function() {
this._freezeSearch = true; this._freezeSearch = true;
this.prepareFilterSelectField(this._selectCategory, this.presetsRepo.index.uniqueValues.category); this.prepareFilterSelectField(this._selectCategory, this.presetsRepo.index.uniqueValues.category, 3);
this.prepareFilterSelectField(this._selectKeyword, this.presetsRepo.index.uniqueValues.keywords); this.prepareFilterSelectField(this._selectKeyword, this.presetsRepo.index.uniqueValues.keywords, 3);
this.prepareFilterSelectField(this._selectAuthor, this.presetsRepo.index.uniqueValues.author); this.prepareFilterSelectField(this._selectAuthor, this.presetsRepo.index.uniqueValues.author, 1);
this.prepareFilterSelectField(this._selectFirmwareVersion, this.presetsRepo.index.uniqueValues.firmware_version); this.prepareFilterSelectField(this._selectFirmwareVersion, this.presetsRepo.index.uniqueValues.firmware_version, 2);
this.prepareFilterSelectField(this._selectStatus, this.presetsRepo.index.settings.PresetStatusEnum); this.prepareFilterSelectField(this._selectStatus, this.presetsRepo.index.settings.PresetStatusEnum, 2);
this.preselectFilterFields(); this.preselectFilterFields();
this._inputTextFilter.on('input', () => this.updateSearchResults()); this._inputTextFilter.on('input', () => this.updateSearchResults());
@ -320,8 +345,6 @@ TABS.presets.prepareFilterFields = function() {
}; };
TABS.presets.preselectFilterFields = function() { TABS.presets.preselectFilterFields = function() {
this._selectCategory.multipleSelect('setSelects', ["TUNE", "RC_SMOOTHING", "RC_LINK", "RATES"]);
const currentVersion = FC.CONFIG.flightControllerVersion; const currentVersion = FC.CONFIG.flightControllerVersion;
const selectedVersions = []; const selectedVersions = [];
@ -334,15 +357,17 @@ TABS.presets.preselectFilterFields = function() {
this._selectFirmwareVersion.multipleSelect('setSelects', selectedVersions); this._selectFirmwareVersion.multipleSelect('setSelects', selectedVersions);
}; };
TABS.presets.prepareFilterSelectField = function(domSelectElement, selectOptions) { TABS.presets.prepareFilterSelectField = function(domSelectElement, selectOptions, minimumCountSelected) {
domSelectElement.multipleSelect("destroy"); domSelectElement.multipleSelect("destroy");
domSelectElement.multipleSelect({ domSelectElement.multipleSelect({
data: selectOptions, data: selectOptions,
placeholder: i18n.getMessage("dropDownAll"), showClear: true,
minimumCountSelected : minimumCountSelected,
placeholder: i18n.getMessage("dropDownFilterDisabled"),
onClick: () => { this.updateSearchResults(); }, onClick: () => { this.updateSearchResults(); },
onCheckAll: () => { this.updateSearchResults(); }, onCheckAll: () => { this.updateSearchResults(); },
onUncheckAll: () => { this.updateSearchResults(); }, onUncheckAll: () => { this.updateSearchResults(); },
formatSelectAll () { return i18n.getMessage("dropDownSelectAll"); }, formatSelectAll() { return i18n.getMessage("dropDownSelectAll"); },
formatAllSelected() { return i18n.getMessage("dropDownAll"); }, formatAllSelected() { return i18n.getMessage("dropDownAll"); },
}); });
}; };
@ -411,6 +436,8 @@ TABS.presets.getFitPresets = function(searchParams) {
} }
} }
result.sort((a, b) => (a.priority > b.priority) ? -1 : 1);
return result; return result;
}; };
@ -478,10 +505,10 @@ TABS.presets.isPresetFitSearchFirmwareVersions = function(preset, searchParams)
TABS.presets.isPresetFitSearchString = function(preset, searchParams) { TABS.presets.isPresetFitSearchString = function(preset, searchParams) {
if (searchParams.searchString) if (searchParams.searchString) {
{
const allKeywords = preset.keywords.join(" "); const allKeywords = preset.keywords.join(" ");
const totalLine = [preset.description, allKeywords, preset.title, preset.author].join("\n").toLowerCase().replace("''", "\""); const allVersions = preset.firmware_version.join(" ");
const totalLine = [preset.description, allKeywords, preset.title, preset.author, allVersions, preset.category].join("\n").toLowerCase().replace("''", "\"");
const allWords = searchParams.searchString.toLowerCase().replace("''", "\"").split(" "); const allWords = searchParams.searchString.toLowerCase().replace("''", "\"").split(" ");
for (const word of allWords) { for (const word of allWords) {