This commit is contained in:
Mario Zechner 2023-06-25 23:52:42 +02:00
commit 2858ca86e4
9 changed files with 70 additions and 57 deletions

View File

@ -1,42 +1,4 @@
<img x-id="loader" class="mx-auto mt-8" src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTM1IiBoZWlnaHQ9IjE0MCIgdmlld0JveD0iMCAwIDEzNSAxNDAiIHhtbG5
zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0icmdiKDIwMSwgODQsIDU4KSI+Ci
AgICA8cmVjdCB5PSIxMCIgd2lkdGg9IjE1IiBoZWlnaHQ9IjEyMCIgcng9IjYiPgogICAgICAgI
DxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImhlaWdodCIKICAgICAgICAgICAgIGJlZ2luPSIwLjVz
IiBkdXI9IjFzIgogICAgICAgICAgICAgdmFsdWVzPSIxMjA7MTEwOzEwMDs5MDs4MDs3MDs2MDs
1MDs0MDsxNDA7MTIwIiBjYWxjTW9kZT0ibGluZWFyIgogICAgICAgICAgICAgcmVwZWF0Q291bn
Q9ImluZGVmaW5pdGUiIC8+CiAgICAgICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0ieSIKICAgI
CAgICAgICAgIGJlZ2luPSIwLjVzIiBkdXI9IjFzIgogICAgICAgICAgICAgdmFsdWVzPSIxMDsx
NTsyMDsyNTszMDszNTs0MDs0NTs1MDswOzEwIiBjYWxjTW9kZT0ibGluZWFyIgogICAgICAgICA
gICAgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIC8+CiAgICA8L3JlY3Q+CiAgICA8cmVjdCB4PS
IzMCIgeT0iMTAiIHdpZHRoPSIxNSIgaGVpZ2h0PSIxMjAiIHJ4PSI2Ij4KICAgICAgICA8YW5pb
WF0ZSBhdHRyaWJ1dGVOYW1lPSJoZWlnaHQiCiAgICAgICAgICAgICBiZWdpbj0iMC4yNXMiIGR1
cj0iMXMiCiAgICAgICAgICAgICB2YWx1ZXM9IjEyMDsxMTA7MTAwOzkwOzgwOzcwOzYwOzUwOzQ
wOzE0MDsxMjAiIGNhbGNNb2RlPSJsaW5lYXIiCiAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW
5kZWZpbml0ZSIgLz4KICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJ5IgogICAgICAgI
CAgICAgYmVnaW49IjAuMjVzIiBkdXI9IjFzIgogICAgICAgICAgICAgdmFsdWVzPSIxMDsxNTsy
MDsyNTszMDszNTs0MDs0NTs1MDswOzEwIiBjYWxjTW9kZT0ibGluZWFyIgogICAgICAgICAgICA
gcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIC8+CiAgICA8L3JlY3Q+CiAgICA8cmVjdCB4PSI2MC
Igd2lkdGg9IjE1IiBoZWlnaHQ9IjE0MCIgcng9IjYiPgogICAgICAgIDxhbmltYXRlIGF0dHJpY
nV0ZU5hbWU9ImhlaWdodCIKICAgICAgICAgICAgIGJlZ2luPSIwcyIgZHVyPSIxcyIKICAgICAg
ICAgICAgIHZhbHVlcz0iMTIwOzExMDsxMDA7OTA7ODA7NzA7NjA7NTA7NDA7MTQwOzEyMCIgY2F
sY01vZGU9ImxpbmVhciIKICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPg
ogICAgICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9InkiCiAgICAgICAgICAgICBiZWdpbj0iM
HMiIGR1cj0iMXMiCiAgICAgICAgICAgICB2YWx1ZXM9IjEwOzE1OzIwOzI1OzMwOzM1OzQwOzQ1
OzUwOzA7MTAiIGNhbGNNb2RlPSJsaW5lYXIiCiAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5
kZWZpbml0ZSIgLz4KICAgIDwvcmVjdD4KICAgIDxyZWN0IHg9IjkwIiB5PSIxMCIgd2lkdGg9Ij
E1IiBoZWlnaHQ9IjEyMCIgcng9IjYiPgogICAgICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9I
mhlaWdodCIKICAgICAgICAgICAgIGJlZ2luPSIwLjI1cyIgZHVyPSIxcyIKICAgICAgICAgICAg
IHZhbHVlcz0iMTIwOzExMDsxMDA7OTA7ODA7NzA7NjA7NTA7NDA7MTQwOzEyMCIgY2FsY01vZGU
9ImxpbmVhciIKICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogICAgIC
AgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9InkiCiAgICAgICAgICAgICBiZWdpbj0iMC4yNXMiI
GR1cj0iMXMiCiAgICAgICAgICAgICB2YWx1ZXM9IjEwOzE1OzIwOzI1OzMwOzM1OzQwOzQ1OzUw
OzA7MTAiIGNhbGNNb2RlPSJsaW5lYXIiCiAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZ
pbml0ZSIgLz4KICAgIDwvcmVjdD4KICAgIDxyZWN0IHg9IjEyMCIgeT0iMTAiIHdpZHRoPSIxNS
IgaGVpZ2h0PSIxMjAiIHJ4PSI2Ij4KICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJoZ
WlnaHQiCiAgICAgICAgICAgICBiZWdpbj0iMC41cyIgZHVyPSIxcyIKICAgICAgICAgICAgIHZh
bHVlcz0iMTIwOzExMDsxMDA7OTA7ODA7NzA7NjA7NTA7NDA7MTQwOzEyMCIgY2FsY01vZGU9Imx
pbmVhciIKICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogICAgICAgID
xhbmltYXRlIGF0dHJpYnV0ZU5hbWU9InkiCiAgICAgICAgICAgICBiZWdpbj0iMC41cyIgZHVyP
SIxcyIKICAgICAgICAgICAgIHZhbHVlcz0iMTA7MTU7MjA7MjU7MzA7MzU7NDA7NDU7NTA7MDsx
MCIgY2FsY01vZGU9ImxpbmVhciIKICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXR
lIiAvPgogICAgPC9yZWN0Pgo8L3N2Zz4=">
<div x-id="loader" class="progress-bar-container mx-auto mt-8">
<div class="progress-bar"></div>
</div>

View File

@ -208,5 +208,4 @@ function loadCart() {
productsList.model = productsFilter.model = models.items;
if (c || d) itemsChart.render();
cartFilter.filter();
document.querySelector('[x-id="loader"]').classList.add("hidden");
})();

View File

@ -71,5 +71,4 @@ function importCarts(importedCarts) {
};
reader.readAsText(event.target.files[0]);
});
document.querySelector('[x-id="loader"]').classList.add("hidden");
})();

View File

@ -38,5 +38,4 @@ require("./views");
}
itemsFilter.model = itemsList.model = model.items;
itemsFilter.fireChangeEvent();
document.querySelector('[x-id="loader"]').classList.add("hidden");
})();

View File

@ -41,5 +41,4 @@ require("./views");
}
itemsFilter.model = itemsList.model = model.items;
itemsFilter.fireChangeEvent();
document.querySelector('[x-id="loader"]').classList.add("hidden");
})();

31
site/js/progress-bar.js Normal file
View File

@ -0,0 +1,31 @@
class ProgressBar {
constructor(steps) {
this.progress = 0;
this.steps = steps ?? 0;
this.step = 100 / this.steps;
this.container = document.querySelector('[x-id="loader"]');
this.progressBar = this.container.querySelector(".progress-bar");
}
setSteps(steps) {
this.steps = steps;
this.step = 100 / steps;
}
addStep() {
this.progress += this.step;
this.progressBar.style.transform = `scaleX(${this.progress / 100})`;
if (this.progress >= 100) {
this.finished();
}
}
finished() {
const element = this.container;
setTimeout(function () {
element.classList.add("hidden");
}, 250);
}
}
exports.ProgressBar = ProgressBar;

View File

@ -2,6 +2,9 @@ const { Model } = require("./model");
const { STORE_KEYS } = require("./stores");
const { Settings } = require("./settings");
const { log, deltaTime } = require("../js/misc");
const { ProgressBar } = require("../js/progress-bar");
const Bar = new ProgressBar(STORE_KEYS.length);
class Items extends Model {
constructor() {
@ -32,6 +35,7 @@ class Items extends Model {
const settings = new Settings();
let start = performance.now();
const compressedItemsPerStore = [];
for (const store of STORE_KEYS) {
compressedItemsPerStore.push(
new Promise(async (resolve) => {
@ -48,9 +52,11 @@ class Items extends Model {
log(`Loader - error while loading compressed items for ${store} ${e.message}`);
resolve([]);
}
Bar.addStep();
})
);
}
let items = [].concat(...(await Promise.all(compressedItemsPerStore)));
log(`Loader - loaded ${items.length} items took ${deltaTime(start).toFixed(4)} secs`);

View File

@ -246,3 +246,20 @@ thead > tr {
a {
@apply hover:underline;
}
/* loading-bar */
.progress-bar-container {
@apply bg-stone-200 rounded-xl;
width: 300px;
height: 10px;
}
.progress-bar {
@apply bg-primary rounded-xl;
height: 10px;
transform: scaleX(0%);
will-change: transform;
transition: scaleX 0.5s;
width: 100%;
transform-origin: left center;
}

View File

@ -212,7 +212,8 @@ class ItemsList extends View {
let highlightedName = name;
for (let i = 0; i < keywords.length; i++) {
const string = keywords[i];
const regex = new RegExp(string, "gi");
// check if keyword is not preceded by a < or </
const regex = new RegExp(`(?<!<\/?)${string}`, "gi");
highlightedName = highlightedName.replace(regex, "<strong>$&</strong>");
}
return `${highlightedName}`;
@ -271,9 +272,9 @@ class ItemsList extends View {
let quantity = item.quantity || "";
let unit = item.unit || "";
if (quantity >= 1000 && (unit == "g" || unit == "ml")) {
if (quantity >= 1000 && (unit === "g" || unit === "ml")) {
quantity = parseFloat((0.001 * quantity).toFixed(2));
unit = unit == "ml" ? "l" : "kg";
unit = unit === "ml" ? "l" : "kg";
}
let percentageChange = "";
if (prevPrice != -1) {
@ -283,8 +284,8 @@ class ItemsList extends View {
let showUnitPrice = this.elements.unitPrice.checked;
let priceUnit = "";
if (showUnitPrice) {
if (item.unit == "g") priceUnit = " / kg";
else if (item.unit == "ml") priceUnit = " / l";
if (item.unit === "g") priceUnit = " / kg";
else if (item.unit === "ml") priceUnit = " / l";
else priceUnit = " / stk";
}
@ -394,7 +395,7 @@ class ItemsList extends View {
elements.up.addEventListener("click", () => {
const index = itemDom.rowIndex - 1;
if (index == 0) return;
if (index === 0) return;
let otherItem = this.model.items[index - 1];
this.model.items[index - 1] = item;
this.model.items[index] = otherItem;
@ -407,7 +408,7 @@ class ItemsList extends View {
elements.down.addEventListener("click", () => {
const index = itemDom.rowIndex - 1;
if (index == this.model.items.length - 1) return;
if (index === this.model.items.length - 1) return;
let otherItem = this.model.items[index + 1];
this.model.items[index + 1] = item;
this.model.items[index] = otherItem;
@ -431,11 +432,11 @@ class ItemsList extends View {
elements.nameSimilarity.removeAttribute("disabled");
} else {
elements.nameSimilarity.setAttribute("disabled", "true");
if (this.model.filteredItems.length != 0 && elements.sort.value == "name-similarity") elements.sort.value = "price-asc";
if (this.model.filteredItems.length != 0 && elements.sort.value === "name-similarity") elements.sort.value = "price-asc";
}
let items = [...this.model.filteredItems];
if (this.model.lastQuery && this.model.lastQuery.charAt(0) == "!" && this.model.lastQuery.toLowerCase().indexOf("order by") >= 0) {
if (this.model.lastQuery && this.model.lastQuery.charAt(0) === "!" && this.model.lastQuery.toLowerCase().indexOf("order by") >= 0) {
elements.sort.parentElement.classList.add("hidden");
} else {
if (!this._noSort) {
@ -443,7 +444,7 @@ class ItemsList extends View {
items = this.sort(items);
}
}
if (items.length == 0) {
if (items.length === 0) {
elements.chart.classList.add("hidden");
elements.options.classList.add("hidden");
elements.itemsTable.classList.add("hidden");
@ -461,7 +462,7 @@ class ItemsList extends View {
const batches = [];
let batch = [];
items.forEach((item) => {
if (batch.length == 25) {
if (batch.length === 25) {
batches.push(batch);
batch = [];
}