diff --git a/src/app_modules.js b/src/app_modules.js
index 13e5ff4..a03d377 100644
--- a/src/app_modules.js
+++ b/src/app_modules.js
@@ -768,281 +768,240 @@ function TS_IndexElement(
return false;
}
- function render() {
- function sorter(a, b) {
- // If both items have Fecha field, sort by date first
- if (a.Fecha && b.Fecha) {
- // Primary sort by date
- if (a.Fecha < b.Fecha) return -1;
- if (a.Fecha > b.Fecha) return 1;
-
- // Secondary sort by Nombre if dates are equal and both have names
- if (a.Nombre && b.Nombre) {
- const nameA = a.Nombre.toLowerCase();
- const nameB = b.Nombre.toLowerCase();
- if (nameA < nameB) return -1;
- if (nameA > nameB) return 1;
- }
- return 0;
- }
- // If persona field exists, sort by Region, then by Nombre
- if (a.Persona && b.Persona) {
- console.log(a.Persona, SC_Personas[a.Persona])
- const personaA = SC_Personas[a.Persona] || { Nombre: "", Region: "" };
- const personaB = SC_Personas[b.Persona] || { Nombre: "", Region: "" };
- if (personaA.Region < personaB.Region) return -1;
- if (personaA.Region > personaB.Region) return 1;
- if (personaA.Nombre < personaB.Nombre) return -1;
- if (personaA.Nombre > personaB.Nombre) return 1;
- return 0;
- }
- // If no Fecha field exists, sort only by Nombre
+ // --- Optimized render function ---
+ let lastSearchValue = "";
+ let lastFilteredSorted = [];
+ function sorter(a, b) {
+ if (a.Fecha && b.Fecha) {
+ if (a.Fecha < b.Fecha) return -1;
+ if (a.Fecha > b.Fecha) return 1;
if (a.Nombre && b.Nombre) {
const nameA = a.Nombre.toLowerCase();
const nameB = b.Nombre.toLowerCase();
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
- return 0;
}
-
return 0;
}
-
- const searchValue = searchKeyEl.value.toLowerCase().trim();
- tablebody_EL.innerHTML = "";
- Object.entries(rows)
+ if (a.Persona && b.Persona) {
+ const personaA = SC_Personas[a.Persona] || { Nombre: "", Region: "" };
+ const personaB = SC_Personas[b.Persona] || { Nombre: "", Region: "" };
+ if (personaA.Region < personaB.Region) return -1;
+ if (personaA.Region > personaB.Region) return 1;
+ if (personaA.Nombre < personaB.Nombre) return -1;
+ if (personaA.Nombre > personaB.Nombre) return 1;
+ return 0;
+ }
+ if (a.Nombre && b.Nombre) {
+ const nameA = a.Nombre.toLowerCase();
+ const nameB = b.Nombre.toLowerCase();
+ if (nameA < nameB) return -1;
+ if (nameA > nameB) return 1;
+ return 0;
+ }
+ return 0;
+ }
+
+ function getFilteredSortedRows(searchValue) {
+ // Only use cache if searchValue is not empty and cache is valid
+ if (searchValue && searchValue === lastSearchValue && lastFilteredSorted.length > 0) {
+ return lastFilteredSorted;
+ }
+ const filtered = Object.entries(rows)
.filter(([_, data]) => searchInData(data, searchValue, config))
.map(([_, data]) => data)
- .sort(sorter)
- .forEach((data) => {
- var new_tr = document.createElement("tr");
-
- if (canAddCallback != undefined) {
- if (canAddCallback(data) == true) {
- return;
+ .sort(sorter);
+ lastSearchValue = searchValue;
+ lastFilteredSorted = filtered;
+ return filtered;
+ }
+
+ function render() {
+ const searchValue = searchKeyEl.value.toLowerCase().trim();
+ // Use document fragment for batch DOM update
+ const fragment = document.createDocumentFragment();
+ const filteredSorted = getFilteredSortedRows(searchValue);
+ for (let i = 0; i < filteredSorted.length; i++) {
+ const data = filteredSorted[i];
+ if (canAddCallback != undefined && canAddCallback(data) === true) {
+ continue;
+ }
+ const new_tr = document.createElement("tr");
+ if (rowCallback != undefined) {
+ rowCallback(data, new_tr);
+ }
+ config.forEach((key) => {
+ switch (key.type) {
+ case "raw":
+ case "text": {
+ const tdRaw = document.createElement("td");
+ const rawContent = (String(data[key.key]) || key.default || "").replace(/\n/g, "
");
+ tdRaw.innerHTML = rawContent;
+ new_tr.appendChild(tdRaw);
+ break;
}
- }
- tablebody_EL.append(new_tr);
- if (rowCallback != undefined) {
- rowCallback(data, new_tr);
- }
- config.forEach((key) => {
- switch (key.type) {
- case "raw":
- case "text":
- const tdRaw = document.createElement("td");
- const rawContent = (String(data[key.key]) || key.default || "").replace(
- /\n/g,
- "
"
- );
- tdRaw.innerHTML = rawContent;
- new_tr.appendChild(tdRaw);
- break;
- case "fecha":
- case "fecha-iso":
- const tdFechaISO = document.createElement("td");
- if (data[key.key]) {
- const fechaArray = data[key.key].split("-");
- tdFechaISO.innerText = fechaArray[2] + "/" + fechaArray[1] + "/" + fechaArray[0];
+ case "fecha":
+ case "fecha-iso": {
+ const tdFechaISO = document.createElement("td");
+ if (data[key.key]) {
+ const fechaArray = data[key.key].split("-");
+ tdFechaISO.innerText = fechaArray[2] + "/" + fechaArray[1] + "/" + fechaArray[0];
+ }
+ new_tr.appendChild(tdFechaISO);
+ break;
+ }
+ case "template": {
+ const tdCustomTemplate = document.createElement("td");
+ new_tr.appendChild(tdCustomTemplate);
+ key.template(data, tdCustomTemplate);
+ break;
+ }
+ case "comanda": {
+ const tdComanda = document.createElement("td");
+ tdComanda.style.verticalAlign = "top";
+ const parsedComanda = JSON.parse(data.Comanda);
+ const precio = SC_priceCalc(parsedComanda)[0];
+ const tempDiv = document.createElement("div");
+ tempDiv.innerHTML = setLayeredImages(parsedComanda, data._key);
+ tdComanda.appendChild(tempDiv.firstChild);
+ const pre = document.createElement("pre");
+ pre.style.fontSize = "15px";
+ pre.style.display = "inline-block";
+ pre.style.margin = "0";
+ pre.style.verticalAlign = "top";
+ pre.style.padding = "5px";
+ pre.style.background = "rgba(255, 255, 0, 0.5)";
+ pre.style.border = "1px solid rgba(0, 0, 0, 0.2)";
+ pre.style.borderRadius = "5px";
+ pre.style.boxShadow = "2px 2px 5px rgba(0, 0, 0, 0.1)";
+ pre.style.height = "100%";
+ const spanPrecio = document.createElement("span");
+ spanPrecio.style.fontSize = "20px";
+ spanPrecio.innerHTML = SC_Personas[data.Persona].Puntos >= 10 ? `Total: Gratis!(${precio}c)` : `Total: ${precio}c`;
+ pre.innerHTML = "Ticket de compra ";
+ pre.appendChild(document.createTextNode("\n"));
+ pre.innerHTML += SC_parse_short(parsedComanda) + "
" + data.Notas + "
";
+ pre.appendChild(spanPrecio);
+ tdComanda.appendChild(pre);
+ new_tr.appendChild(tdComanda);
+ break;
+ }
+ case "comanda-status": {
+ var sc_nobtn = "";
+ if (urlParams.get("sc_nobtn") == "yes") {
+ sc_nobtn = "pointer-events: none; opacity: 0.5";
+ }
+ const td = document.createElement("td");
+ td.style.fontSize = "17px";
+ if (sc_nobtn) {
+ td.style.pointerEvents = "none";
+ td.style.opacity = "0.5";
+ }
+ const createButton = (text, state) => {
+ const button = document.createElement("button");
+ button.textContent = text;
+ if (data.Estado === state) {
+ button.className = "rojo";
}
- new_tr.appendChild(tdFechaISO);
- break;
- case "template":
- const tdCustomTemplate = document.createElement("td");
- new_tr.appendChild(tdCustomTemplate);
- key.template(data, tdCustomTemplate);
- break;
- case "comanda":
- const tdComanda = document.createElement("td");
- tdComanda.style.verticalAlign = "top";
- const parsedComanda = JSON.parse(data.Comanda);
- const precio = SC_priceCalc(parsedComanda)[0];
-
- // Create a temporary div to parse the HTML from setLayeredImages
- const tempDiv = document.createElement("div");
- tempDiv.innerHTML = setLayeredImages(parsedComanda, data._key);
- tdComanda.appendChild(tempDiv.firstChild);
-
- const pre = document.createElement("pre");
- pre.style.fontSize = "15px";
- pre.style.display = "inline-block";
- pre.style.margin = "0";
- pre.style.verticalAlign = "top";
- pre.style.padding = "5px";
- //looking like a post-it
- pre.style.background = "rgba(255, 255, 0, 0.5)";
- pre.style.border = "1px solid rgba(0, 0, 0, 0.2)";
- pre.style.borderRadius = "5px";
- pre.style.boxShadow = "2px 2px 5px rgba(0, 0, 0, 0.1)";
- pre.style.height = "100%";
- const spanPrecio = document.createElement("span");
- spanPrecio.style.fontSize = "20px";
- spanPrecio.innerHTML =
- SC_Personas[data.Persona].Puntos >= 10 ?
- `Total: Gratis!(${precio}c)` :
- `Total: ${precio}c`;
- pre.innerHTML = "Ticket de compra ";
- pre.appendChild(document.createTextNode("\n"));
- pre.innerHTML +=
- SC_parse_short(parsedComanda) + "
" + data.Notas + "
";
- pre.appendChild(spanPrecio);
-
- tdComanda.appendChild(pre);
- new_tr.appendChild(tdComanda);
- break;
- case "comanda-status":
- var sc_nobtn = "";
- if (urlParams.get("sc_nobtn") == "yes") {
- sc_nobtn = "pointer-events: none; opacity: 0.5";
- }
- const td = document.createElement("td");
- td.style.fontSize = "17px";
- if (sc_nobtn) {
- td.style.pointerEvents = "none";
- td.style.opacity = "0.5";
- }
-
- // Create buttons
- const createButton = (text, state) => {
- const button = document.createElement("button");
- button.textContent = text;
- if (data.Estado === state) {
- button.className = "rojo";
- }
- button.onclick = (event) => {
- event.preventDefault();
- event.stopPropagation();
- data.Estado = state;
- var enc = TS_encrypt(data, SECRET, (encrypted) => {
- betterGunPut(ref.get(data._key), encrypted);
- toastr.success("Guardado!");
- });
- return false;
- };
- return button;
- };
-
- // Create all buttons
- const buttons = [
- createButton("Pedido", "Pedido"),
- createButton("En preparación", "En preparación"),
- createButton("Listo", "Listo"),
- createButton("Entregado", "Entregado"),
- createButton("Deuda", "Deuda"),
- ];
-
- // Create paid button separately due to different behavior
- const paidButton = document.createElement("button");
- paidButton.textContent = "Pagado";
- paidButton.onclick = (event) => {
+ button.onclick = (event) => {
event.preventDefault();
event.stopPropagation();
- if (
- !confirm(
- "¿Quieres marcar como pagado? - Se borrara la comanda y se actualizarán los puntos."
- )
- ) {
- return false;
- }
- data.Estado = "Pagado";
- betterGunPut(ref.get(data._key), null);
- toastr.success("Guardado!");
- if (SC_Personas[data.Persona].Puntos >= 10 && confirm("¿Pagar con Puntos? - Cancela para pagar con Efectivo.")) {
- SC_Personas[data.Persona].Puntos = parseInt(SC_Personas[data.Persona].Puntos) - 10;
- toastr.success(
- "¡Comada gratis para " +
- SC_Personas[data.Persona].Nombre +
- "!"
- );
- toastr.success(
- "¡Comada gratis para " +
- SC_Personas[data.Persona].Nombre +
- "!"
- );
- } else {
- SC_Personas[data.Persona].Puntos = parseInt(SC_Personas[data.Persona].Puntos) + 1;
- toastr.success("¡Comada DE PAGO!");
- }
- TS_encrypt(SC_Personas[data.Persona], SECRET, (encrypted) => {
- betterGunPut(
- gun.get(TABLE).get("personas").get(data.Persona),
- encrypted
- );
+ data.Estado = state;
+ TS_encrypt(data, SECRET, (encrypted) => {
+ betterGunPut(ref.get(data._key), encrypted);
+ toastr.success("Guardado!");
});
return false;
};
-
- // Add all buttons to td with line breaks between
- buttons.forEach((button) => {
- td.appendChild(button);
- td.appendChild(document.createElement("br"));
- });
- td.appendChild(paidButton);
- new_tr.appendChild(td);
-
- // Event handlers are now attached during button creation
- break;
- case "persona":
- if (key.self == true) {
- var persona = data
- } else {
- var persona = SC_Personas[data[key.key]] || {};
+ return button;
+ };
+ const buttons = [
+ createButton("Pedido", "Pedido"),
+ createButton("En preparación", "En preparación"),
+ createButton("Listo", "Listo"),
+ createButton("Entregado", "Entregado"),
+ createButton("Deuda", "Deuda"),
+ ];
+ const paidButton = document.createElement("button");
+ paidButton.textContent = "Pagado";
+ paidButton.onclick = (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ if (!confirm("¿Quieres marcar como pagado? - Se borrara la comanda y se actualizarán los puntos.")) {
+ return false;
}
-
- const regco = stringToColour(
- (persona.Region || "?").toLowerCase()
- );
-
- const tdPersona = document.createElement("td");
- tdPersona.style.textAlign = "center";
- tdPersona.style.fontSize = "20px";
- tdPersona.style.backgroundColor = regco;
- tdPersona.style.color = colorIsDarkAdvanced(regco);
-
- const regionSpan = document.createElement("span");
- regionSpan.style.fontSize = "40px";
- regionSpan.style.textTransform = "capitalize";
- regionSpan.textContent = (persona.Region || "?").toLowerCase();
- tdPersona.appendChild(regionSpan);
-
- tdPersona.appendChild(document.createElement("br"));
-
- const infoSpan = document.createElement("span");
- infoSpan.style.backgroundColor = "white";
- infoSpan.style.border = "2px solid black";
- infoSpan.style.borderRadius = "5px";
- infoSpan.style.display = "inline-block";
- infoSpan.style.padding = "5px";
- infoSpan.style.color = "black";
-
- const img = document.createElement("img");
- img.src = persona.Foto || "static/ico/user_generic.png";
- img.height = 70;
- infoSpan.appendChild(img);
-
- infoSpan.appendChild(document.createElement("br"));
- infoSpan.appendChild(
- document.createTextNode(persona.Nombre || "")
- );
-
- infoSpan.appendChild(document.createElement("br"));
- const pointsSpan = document.createElement("span");
- pointsSpan.style.fontSize = "17px";
- pointsSpan.textContent = (persona.Puntos || "0") + " puntos.";
- infoSpan.appendChild(pointsSpan);
-
- tdPersona.appendChild(infoSpan);
- new_tr.appendChild(tdPersona);
- break;
-
- default:
- break;
+ data.Estado = "Pagado";
+ betterGunPut(ref.get(data._key), null);
+ toastr.success("Guardado!");
+ if (SC_Personas[data.Persona].Puntos >= 10 && confirm("¿Pagar con Puntos? - Cancela para pagar con Efectivo.")) {
+ SC_Personas[data.Persona].Puntos = parseInt(SC_Personas[data.Persona].Puntos) - 10;
+ toastr.success("¡Comada gratis para " + SC_Personas[data.Persona].Nombre + "!");
+ toastr.success("¡Comada gratis para " + SC_Personas[data.Persona].Nombre + "!");
+ } else {
+ SC_Personas[data.Persona].Puntos = parseInt(SC_Personas[data.Persona].Puntos) + 1;
+ toastr.success("¡Comada DE PAGO!");
+ }
+ TS_encrypt(SC_Personas[data.Persona], SECRET, (encrypted) => {
+ betterGunPut(gun.get(TABLE).get("personas").get(data.Persona), encrypted);
+ });
+ return false;
+ };
+ buttons.forEach((button) => {
+ td.appendChild(button);
+ td.appendChild(document.createElement("br"));
+ });
+ td.appendChild(paidButton);
+ new_tr.appendChild(td);
+ break;
}
- });
- new_tr.onclick = (event) => {
- setUrlHash(pageco + "," + data._key);
- };
+ case "persona": {
+ let persona = key.self === true ? data : SC_Personas[data[key.key]] || {};
+ const regco = stringToColour((persona.Region || "?").toLowerCase());
+ const tdPersona = document.createElement("td");
+ tdPersona.style.textAlign = "center";
+ tdPersona.style.fontSize = "20px";
+ tdPersona.style.backgroundColor = regco;
+ tdPersona.style.color = colorIsDarkAdvanced(regco);
+ const regionSpan = document.createElement("span");
+ regionSpan.style.fontSize = "40px";
+ regionSpan.style.textTransform = "capitalize";
+ regionSpan.textContent = (persona.Region || "?").toLowerCase();
+ tdPersona.appendChild(regionSpan);
+ tdPersona.appendChild(document.createElement("br"));
+ const infoSpan = document.createElement("span");
+ infoSpan.style.backgroundColor = "white";
+ infoSpan.style.border = "2px solid black";
+ infoSpan.style.borderRadius = "5px";
+ infoSpan.style.display = "inline-block";
+ infoSpan.style.padding = "5px";
+ infoSpan.style.color = "black";
+ const img = document.createElement("img");
+ img.src = persona.Foto || "static/ico/user_generic.png";
+ img.height = 70;
+ infoSpan.appendChild(img);
+ infoSpan.appendChild(document.createElement("br"));
+ infoSpan.appendChild(document.createTextNode(persona.Nombre || ""));
+ infoSpan.appendChild(document.createElement("br"));
+ const pointsSpan = document.createElement("span");
+ pointsSpan.style.fontSize = "17px";
+ pointsSpan.textContent = (persona.Puntos || "0") + " puntos.";
+ infoSpan.appendChild(pointsSpan);
+ tdPersona.appendChild(infoSpan);
+ new_tr.appendChild(tdPersona);
+ break;
+ }
+ default:
+ break;
+ }
});
+ new_tr.onclick = (event) => {
+ setUrlHash(pageco + "," + data._key);
+ };
+ fragment.appendChild(new_tr);
+ }
+ // Replace tbody in one operation
+ tablebody_EL.innerHTML = "";
+ tablebody_EL.appendChild(fragment);
}
ref.map().on((data, key, _msg, _ev) => {
EventListeners.GunJS.push(_ev);
diff --git a/src/page/materiales.js b/src/page/materiales.js
index adaf9a9..dd5d292 100644
--- a/src/page/materiales.js
+++ b/src/page/materiales.js
@@ -175,12 +175,11 @@ PAGES.materiales = {
gun.get(TABLE).get("materiales"),
document.getElementById("tableContainer"),
undefined,
- undefined,
- //function(data) {
- // if (data.Ubicacion == filtroUbicacion) {return false}
- // if (filtroUbicacion == "") {return false}
- // return true
- //}
+ function(data) {
+ if (data.Ubicacion == filtroUbicacion) {return false}
+ if (filtroUbicacion == "") {return false}
+ return true
+ }
);
}