Merge pull request #273 from RubenPX/feature/lots-search

Feature: lots-search US 3334
This commit is contained in:
Santiago L 2022-05-23 13:39:42 +02:00 committed by GitHub
commit 7d7507c1d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 469 additions and 360 deletions

View File

@ -28,7 +28,7 @@
"class-methods-use-this": "off", "class-methods-use-this": "off",
"eqeqeq": "warn", "eqeqeq": "warn",
"radix": "warn", "radix": "warn",
"max-classes-per-file": ["error", 2] "max-classes-per-file": "warn"
}, },
"globals": { "globals": {
"API_URLS": true, "API_URLS": true,

View File

@ -8,6 +8,7 @@ ml).
## master ## master
## testing ## testing
- [added] #273 Allow search/filter lots on lots management component.
## [2.1.1] - 2022-05-11 ## [2.1.1] - 2022-05-11
Hot fix release. Hot fix release.

View File

@ -218,9 +218,13 @@
/** /**
* Avoid hide dropdown when user clicked inside * Avoid hide dropdown when user clicked inside
*/ */
document.getElementById("dropDownLotsSelector").addEventListener("click", event => { const dropdownLotSelector = document.getElementById("dropDownLotsSelector")
if (dropdownLotSelector != null) { // If exists selector it will set click event
dropdownLotSelector.addEventListener("click", event => {
event.stopPropagation(); event.stopPropagation();
}) })
}
/** /**
* Search form functionality * Search form functionality

View File

@ -1,5 +1,7 @@
"use strict"; "use strict";
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { _classCheckPrivateStaticAccess(receiver, classConstructor); _classCheckPrivateStaticFieldDescriptor(descriptor, "get"); return _classApplyDescriptorGet(receiver, descriptor); } function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) { _classCheckPrivateStaticAccess(receiver, classConstructor); _classCheckPrivateStaticFieldDescriptor(descriptor, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
function _classCheckPrivateStaticFieldDescriptor(descriptor, action) { if (descriptor === undefined) { throw new TypeError("attempted to " + action + " private static field before its declaration"); } } function _classCheckPrivateStaticFieldDescriptor(descriptor, action) { if (descriptor === undefined) { throw new TypeError("attempted to " + action + " private static field before its declaration"); } }
@ -328,11 +330,59 @@ function export_file(type_file) {
$("#exportAlertModal").click(); $("#exportAlertModal").click();
} }
} }
class lotsSearcher {
static enable() {
if (this.lotsSearchElement) this.lotsSearchElement.disabled = false;
}
static disable() {
if (this.lotsSearchElement) this.lotsSearchElement.disabled = true;
}
/**
* do search when lot change in the search input
*/
static doSearch(inputSearch) {
const lots = this.getListLots();
for (let i = 0; i < lots.length; i++) {
if (lot.innerText.toLowerCase().includes(inputSearch.toLowerCase())) {
lot.parentElement.style.display = "";
} else {
lot.parentElement.style.display = "none";
}
}
}
}
_defineProperty(lotsSearcher, "lots", []);
_defineProperty(lotsSearcher, "lotsSearchElement", null);
_defineProperty(lotsSearcher, "getListLots", () => {
let lotsList = document.getElementById("LotsSelector");
if (lotsList) {
// Apply filter to get only labels
return Array.from(lotsList.children).filter(item => item.querySelector("label"));
}
return [];
});
document.addEventListener("DOMContentLoaded", () => {
lotsSearcher.lotsSearchElement = document.getElementById("lots-search");
lotsSearcher.lotsSearchElement.addEventListener("input", e => {
lotsSearcher.doSearch(e.target.value);
});
});
/** /**
* Reactive lots button * Reactive lots button
*/ */
async function processSelectedDevices() { async function processSelectedDevices() {
class Actions { class Actions {
constructor() { constructor() {
@ -584,6 +634,7 @@ async function processSelectedDevices() {
document.getElementById("ApplyDeviceLots").classList.add("disabled"); document.getElementById("ApplyDeviceLots").classList.add("disabled");
try { try {
lotsSearcher.disable();
listHTML.html("<li style=\"text-align: center\"><div class=\"spinner-border text-info\" style=\"margin: auto\" role=\"status\"></div></li>"); listHTML.html("<li style=\"text-align: center\"><div class=\"spinner-border text-info\" style=\"margin: auto\" role=\"status\"></div></li>");
const selectedDevices = await Api.get_devices(selectedDevicesID); const selectedDevices = await Api.get_devices(selectedDevicesID);
let lots = await Api.get_lots(); let lots = await Api.get_lots();
@ -614,6 +665,7 @@ async function processSelectedDevices() {
listHTML.html(""); listHTML.html("");
lotsList.forEach(lot => templateLot(lot, selectedDevices, listHTML, actions)); lotsList.forEach(lot => templateLot(lot, selectedDevices, listHTML, actions));
lotsSearcher.enable();
} catch (error) { } catch (error) {
console.log(error); console.log(error);
listHTML.html("<li style=\"color: red; text-align: center\">Error feching devices and lots<br>(see console for more details)</li>"); listHTML.html("<li style=\"color: red; text-align: center\">Error feching devices and lots<br>(see console for more details)</li>");

View File

@ -317,6 +317,47 @@ function export_file(type_file) {
} }
} }
class lotsSearcher {
static lots = [];
static lotsSearchElement = null;
static getListLots = () => {
const lotsList = document.getElementById("LotsSelector")
if (lotsList) {
// Apply filter to get only labels
return Array.from(lotsList.children).filter(item => item.querySelector("label"));
}
return [];
}
static enable() {
if (this.lotsSearchElement) this.lotsSearchElement.disabled = false;
}
static disable() {
if (this.lotsSearchElement) this.lotsSearchElement.disabled = true;
}
/**
* do search when lot change in the search input
*/
static doSearch(inputSearch) {
const lots = this.getListLots();
for (let i = 0; i < lots.length; i++) {
if (lot.innerText.toLowerCase().includes(inputSearch.toLowerCase())) {
lot.parentElement.style.display = "";
} else {
lot.parentElement.style.display = "none";
}
}
}
}
document.addEventListener("DOMContentLoaded", () => {
lotsSearcher.lotsSearchElement = document.getElementById("lots-search");
lotsSearcher.lotsSearchElement.addEventListener("input", (e) => { lotsSearcher.doSearch(e.target.value) })
})
/** /**
* Reactive lots button * Reactive lots button
@ -557,6 +598,7 @@ async function processSelectedDevices() {
document.getElementById("ApplyDeviceLots").classList.add("disabled"); document.getElementById("ApplyDeviceLots").classList.add("disabled");
try { try {
lotsSearcher.disable()
listHTML.html("<li style=\"text-align: center\"><div class=\"spinner-border text-info\" style=\"margin: auto\" role=\"status\"></div></li>") listHTML.html("<li style=\"text-align: center\"><div class=\"spinner-border text-info\" style=\"margin: auto\" role=\"status\"></div></li>")
const selectedDevices = await Api.get_devices(selectedDevicesID); const selectedDevices = await Api.get_devices(selectedDevicesID);
let lots = await Api.get_lots(); let lots = await Api.get_lots();
@ -589,6 +631,7 @@ async function processSelectedDevices() {
listHTML.html(""); listHTML.html("");
lotsList.forEach(lot => templateLot(lot, selectedDevices, listHTML, actions)); lotsList.forEach(lot => templateLot(lot, selectedDevices, listHTML, actions));
lotsSearcher.enable();
} catch (error) { } catch (error) {
console.log(error); console.log(error);
listHTML.html("<li style=\"color: red; text-align: center\">Error feching devices and lots<br>(see console for more details)</li>"); listHTML.html("<li style=\"color: red; text-align: center\">Error feching devices and lots<br>(see console for more details)</li>");

View File

@ -87,7 +87,16 @@
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<span class="d-none" id="activeTradeModal" data-bs-toggle="modal" data-bs-target="#tradeLotModal"></span> <span class="d-none" id="activeTradeModal" data-bs-toggle="modal" data-bs-target="#tradeLotModal"></span>
<ul class="dropdown-menu" aria-labelledby="btnLots" id="dropDownLotsSelector"> <ul class="dropdown-menu" aria-labelledby="btnLots" id="dropDownLotsSelector">
<div class="row w-100">
<div class="input-group mb-3 mx-2">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1"><i class="bi bi-search"></i></span>
</div>
<input type="text" class="form-control" id="lots-search" placeholder="search" aria-label="search" aria-describedby="basic-addon1">
</div>
</div>
<h6 class="dropdown-header">Select lots where to store the selected devices</h6> <h6 class="dropdown-header">Select lots where to store the selected devices</h6>
<ul class="mx-3" id="LotsSelector"></ul> <ul class="mx-3" id="LotsSelector"></ul>
<li><hr /></li> <li><hr /></li>