FASE 7: Quick Wins de Performance — Optimización Fase 1
Cambios implementados: 1. Nginx: - gzip on (compresión JS/CSS/JSON) - Cache headers para assets estáticos (6M) - Proxy buffer tuning (10s connect, 30s read) 2. Frontend catalog.js: - Reemplazados 8x innerHTML += en loops por map+join - Event delegation en breadcrumb y cart (elimina memory leak) - AbortController en apiFetch (evita race conditions) - sessionStorage cache para years-all y brands por modo 3. Frontend templates HTML: - defer en todos los scripts POS (mejora First Paint) 4. Dashboard JS: - innerHTML += fix en dashboard.js y cuentas.js 5. Base de datos: - Índice parcial idx_wi_part_stock_positive en warehouse_inventory 6. Documentación: - docs/performance_audit_2026.md con análisis completo y roadmap Tests: 73/73 pasando (compat + fase3 + fase5 + fase6)
This commit is contained in:
@@ -186,8 +186,20 @@
|
||||
var cartItems = JSON.parse(localStorage.getItem('pos_cart') || '[]');
|
||||
|
||||
// ─── API helper ───
|
||||
var currentAbort = null;
|
||||
|
||||
function apiFetch(url) {
|
||||
return fetch(url, { headers: headers })
|
||||
// Cancel previous navigation/search GETs to avoid race conditions
|
||||
if (currentAbort) {
|
||||
currentAbort.abort();
|
||||
currentAbort = null;
|
||||
}
|
||||
var opts = { headers: headers };
|
||||
if (url.indexOf('/pos/api/') === 0 && url.indexOf('mode=') !== -1 || url.indexOf('/years') !== -1 || url.indexOf('/brands') !== -1 || url.indexOf('/models') !== -1 || url.indexOf('/engines') !== -1 || url.indexOf('/categories') !== -1 || url.indexOf('/groups') !== -1 || url.indexOf('/part-types') !== -1 || url.indexOf('/parts') !== -1 || url.indexOf('/search') !== -1) {
|
||||
currentAbort = new AbortController();
|
||||
opts.signal = currentAbort.signal;
|
||||
}
|
||||
return fetch(url, opts)
|
||||
.then(function (resp) {
|
||||
if (resp.status === 401) {
|
||||
localStorage.removeItem('pos_token');
|
||||
@@ -197,6 +209,7 @@
|
||||
return resp.json();
|
||||
})
|
||||
.catch(function (e) {
|
||||
if (e.name === 'AbortError') return null;
|
||||
console.error('API error:', e);
|
||||
return null;
|
||||
});
|
||||
@@ -333,8 +346,18 @@
|
||||
setupLevelFilter(true);
|
||||
showLoading();
|
||||
|
||||
var cacheKey = 'nexus:brands:' + catalogMode;
|
||||
var cached = sessionStorage.getItem(cacheKey);
|
||||
if (cached) {
|
||||
hideLoading();
|
||||
var data = JSON.parse(cached);
|
||||
renderBrands(data);
|
||||
return;
|
||||
}
|
||||
|
||||
apiFetch(API + '/brands?mode=' + catalogMode).then(function (data) {
|
||||
hideLoading();
|
||||
if (data && data.data) sessionStorage.setItem(cacheKey, JSON.stringify(data));
|
||||
if (!data || !data.data || !data.data.length) {
|
||||
if (!data) {
|
||||
enterOfflineMode();
|
||||
@@ -359,6 +382,30 @@
|
||||
});
|
||||
}
|
||||
|
||||
function renderBrands(data) {
|
||||
if (!data || !data.data || !data.data.length) {
|
||||
if (!data) {
|
||||
enterOfflineMode();
|
||||
return;
|
||||
}
|
||||
showEmpty('Sin marcas', 'El catalogo no tiene marcas con partes disponibles.');
|
||||
return;
|
||||
}
|
||||
navGrid.className = 'nav-grid';
|
||||
navGrid.innerHTML = data.data.map(function (b) {
|
||||
return '<div class="nav-card" role="listitem" data-brand-id="' + b.id_brand + '" data-name="' + esc(b.name_brand) + '">' +
|
||||
'<div class="nav-card__name">' + esc(b.name_brand) + '</div>' +
|
||||
'</div>';
|
||||
}).join('');
|
||||
|
||||
navGrid.querySelectorAll('.nav-card').forEach(function (card) {
|
||||
card.addEventListener('click', function () {
|
||||
nav.brand = { id: parseInt(this.dataset.brandId), name: this.dataset.name };
|
||||
loadModels();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function loadModels() {
|
||||
nav.level = 'models';
|
||||
pushNavState();
|
||||
@@ -1463,18 +1510,19 @@
|
||||
cartTaxEl.textContent = '$' + fmt(tax);
|
||||
cartTotalEl.textContent = '$' + fmt(subtotal + tax);
|
||||
|
||||
// Wire cart buttons
|
||||
cartItemsEl.querySelectorAll('[data-cart-action]').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
var idx = parseInt(this.dataset.idx);
|
||||
var action = this.dataset.cartAction;
|
||||
if (action === 'dec') updateQuantity(idx, cartItems[idx].quantity - 1);
|
||||
else if (action === 'inc') updateQuantity(idx, cartItems[idx].quantity + 1);
|
||||
else if (action === 'remove') removeFromCart(idx);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Event delegation for cart buttons (attached once)
|
||||
cartItemsEl.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest('[data-cart-action]');
|
||||
if (!btn) return;
|
||||
var idx = parseInt(btn.dataset.idx);
|
||||
var action = btn.dataset.cartAction;
|
||||
if (action === 'dec') updateQuantity(idx, cartItems[idx].quantity - 1);
|
||||
else if (action === 'inc') updateQuantity(idx, cartItems[idx].quantity + 1);
|
||||
else if (action === 'remove') removeFromCart(idx);
|
||||
});
|
||||
|
||||
function toggleCart() {
|
||||
var isOpen = cartSidebar.classList.toggle('open');
|
||||
cartOverlay.classList.toggle('open', isOpen);
|
||||
@@ -1565,6 +1613,22 @@
|
||||
|
||||
// Load years on init
|
||||
function vsLoadYears() {
|
||||
var cacheKey = 'nexus:years-all';
|
||||
var cached = sessionStorage.getItem(cacheKey);
|
||||
if (cached) {
|
||||
var data = JSON.parse(cached);
|
||||
var years = data.data || data || [];
|
||||
if (!years.length) {
|
||||
years = [];
|
||||
for (var y = 2026; y >= 1990; y--) years.push({ id_year: y, year_car: y });
|
||||
}
|
||||
vsYear.innerHTML = '<option value="">Año...</option>' +
|
||||
years.map(function (y) {
|
||||
return '<option value="' + y.id_year + '">' + y.year_car + '</option>';
|
||||
}).join('');
|
||||
return;
|
||||
}
|
||||
|
||||
apiFetch(API + '/years-all').then(function (data) {
|
||||
if (!data) return;
|
||||
var years = data.data || data;
|
||||
@@ -1573,16 +1637,19 @@
|
||||
years = [];
|
||||
for (var y = 2026; y >= 1990; y--) years.push({ id_year: y, year_car: y });
|
||||
}
|
||||
vsYear.innerHTML = '<option value="">Año...</option>';
|
||||
years.forEach(function (y) {
|
||||
vsYear.innerHTML += '<option value="' + y.id_year + '">' + y.year_car + '</option>';
|
||||
});
|
||||
sessionStorage.setItem(cacheKey, JSON.stringify(data));
|
||||
vsYear.innerHTML = '<option value="">Año...</option>' +
|
||||
years.map(function (y) {
|
||||
return '<option value="' + y.id_year + '">' + y.year_car + '</option>';
|
||||
}).join('');
|
||||
}).catch(function () {
|
||||
// Fallback: generate years statically
|
||||
vsYear.innerHTML = '<option value="">Año...</option>';
|
||||
for (var y = 2026; y >= 1990; y--) {
|
||||
vsYear.innerHTML += '<option value="' + y + '">' + y + '</option>';
|
||||
}
|
||||
var fallbackYears = [];
|
||||
for (var y = 2026; y >= 1990; y--) fallbackYears.push(y);
|
||||
vsYear.innerHTML = '<option value="">Año...</option>' +
|
||||
fallbackYears.map(function (y) {
|
||||
return '<option value="' + y + '">' + y + '</option>';
|
||||
}).join('');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1603,10 +1670,10 @@
|
||||
apiFetch(API + '/brands?year_id=' + yearId + '&mode=' + catalogMode).then(function (data) {
|
||||
var brands = data.data || data;
|
||||
if (!brands) return;
|
||||
vsBrand.innerHTML = '<option value="">Marca...</option>';
|
||||
brands.forEach(function (b) {
|
||||
vsBrand.innerHTML += '<option value="' + b.id_brand + '">' + esc(b.name_brand) + '</option>';
|
||||
});
|
||||
vsBrand.innerHTML = '<option value="">Marca...</option>' +
|
||||
brands.map(function (b) {
|
||||
return '<option value="' + b.id_brand + '">' + esc(b.name_brand) + '</option>';
|
||||
}).join('');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1625,10 +1692,10 @@
|
||||
apiFetch(API + '/models?brand_id=' + brandId + (yearId ? '&year_id=' + yearId : '')).then(function (data) {
|
||||
var models = data.data || data;
|
||||
if (!models) return;
|
||||
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
||||
models.forEach(function (m) {
|
||||
vsModel.innerHTML += '<option value="' + m.id_model + '">' + esc(m.display_name || m.name_model) + '</option>';
|
||||
});
|
||||
vsModel.innerHTML = '<option value="">Modelo...</option>' +
|
||||
models.map(function (m) {
|
||||
return '<option value="' + m.id_model + '">' + esc(m.display_name || m.name_model) + '</option>';
|
||||
}).join('');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1644,11 +1711,11 @@
|
||||
apiFetch(API + '/engines?model_id=' + modelId + '&year_id=' + yearVal).then(function (data) {
|
||||
var engines = data.data || data;
|
||||
if (!engines) return;
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
||||
engines.forEach(function (e) {
|
||||
var label = e.name_engine + (e.trim_level ? ' (' + e.trim_level + ')' : '');
|
||||
vsEngine.innerHTML += '<option value="' + e.id_mye + '">' + esc(label) + '</option>';
|
||||
});
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>' +
|
||||
engines.map(function (e) {
|
||||
var label = e.name_engine + (e.trim_level ? ' (' + e.trim_level + ')' : '');
|
||||
return '<option value="' + e.id_mye + '">' + esc(label) + '</option>';
|
||||
}).join('');
|
||||
// If only 1 engine, auto-select
|
||||
if (engines.length === 1) {
|
||||
vsEngine.value = engines[0].id_mye;
|
||||
@@ -1841,10 +1908,10 @@
|
||||
apiFetch(API + '/brands?year_id=' + match.year_id).then(function (brandData) {
|
||||
var brands = brandData && (brandData.data || brandData);
|
||||
if (!brands) return;
|
||||
vsBrand.innerHTML = '<option value="">Marca...</option>';
|
||||
brands.forEach(function (b) {
|
||||
vsBrand.innerHTML += '<option value="' + b.id_brand + '">' + esc(b.name_brand) + '</option>';
|
||||
});
|
||||
vsBrand.innerHTML = '<option value="">Marca...</option>' +
|
||||
brands.map(function (b) {
|
||||
return '<option value="' + b.id_brand + '">' + esc(b.name_brand) + '</option>';
|
||||
}).join('');
|
||||
vsBrand.disabled = false;
|
||||
vsClear.style.display = '';
|
||||
|
||||
@@ -1854,10 +1921,10 @@
|
||||
apiFetch(API + '/models?brand_id=' + match.brand_id + '&year_id=' + match.year_id).then(function (modelData) {
|
||||
var models = modelData && (modelData.data || modelData);
|
||||
if (!models) return;
|
||||
vsModel.innerHTML = '<option value="">Modelo...</option>';
|
||||
models.forEach(function (m) {
|
||||
vsModel.innerHTML += '<option value="' + m.id_model + '">' + esc(m.display_name || m.name_model) + '</option>';
|
||||
});
|
||||
vsModel.innerHTML = '<option value="">Modelo...</option>' +
|
||||
models.map(function (m) {
|
||||
return '<option value="' + m.id_model + '">' + esc(m.display_name || m.name_model) + '</option>';
|
||||
}).join('');
|
||||
vsModel.disabled = false;
|
||||
|
||||
if (match.model_id) {
|
||||
@@ -1866,11 +1933,11 @@
|
||||
apiFetch(API + '/engines?model_id=' + match.model_id + '&year_id=' + match.year_id).then(function (engData) {
|
||||
var engines = engData && (engData.data || engData);
|
||||
if (!engines) return;
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>';
|
||||
engines.forEach(function (e) {
|
||||
var elabel = e.name_engine + (e.trim_level ? ' (' + e.trim_level + ')' : '');
|
||||
vsEngine.innerHTML += '<option value="' + e.id_mye + '">' + esc(elabel) + '</option>';
|
||||
});
|
||||
vsEngine.innerHTML = '<option value="">Motor...</option>' +
|
||||
engines.map(function (e) {
|
||||
var elabel = e.name_engine + (e.trim_level ? ' (' + e.trim_level + ')' : '');
|
||||
return '<option value="' + e.id_mye + '">' + esc(elabel) + '</option>';
|
||||
}).join('');
|
||||
vsEngine.disabled = false;
|
||||
|
||||
// Auto-select engine if only one or if match specifies it
|
||||
|
||||
@@ -1731,12 +1731,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/accounting.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/accounting.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<link rel="stylesheet" href="/pos/static/css/onboarding.css" />
|
||||
<link rel="manifest" href="/pos/static/pwa/manifest.json" />
|
||||
<meta name="theme-color" content="#F5A623" />
|
||||
<script src="/pos/static/js/native-bridge.js"></script>
|
||||
<script src="/pos/static/js/native-bridge.js" defer></script>
|
||||
|
||||
<style>
|
||||
/* =========================================================================
|
||||
@@ -820,16 +820,16 @@
|
||||
<button class="banner__dismiss" onclick="document.getElementById('offlineBanner').style.display='none'" aria-label="Cerrar">×</button>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/kiosk.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/catalog.js"></script>
|
||||
<script src="/pos/static/js/offline-banner.js"></script>
|
||||
<script src="/pos/static/js/chat.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/onboarding.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/kiosk.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/catalog.js" defer></script>
|
||||
<script src="/pos/static/js/offline-banner.js" defer></script>
|
||||
<script src="/pos/static/js/chat.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script src="/pos/static/js/onboarding.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1880,13 +1880,13 @@
|
||||
@keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
|
||||
</style>
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/kiosk.js"></script>
|
||||
<script src="/pos/static/js/config.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/kiosk.js" defer></script>
|
||||
<script src="/pos/static/js/config.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -2164,13 +2164,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/customers.js"></script>
|
||||
<script src="/pos/static/js/offline-banner.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/customers.js" defer></script>
|
||||
<script src="/pos/static/js/offline-banner.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1686,12 +1686,12 @@
|
||||
</div><!-- end app-shell -->
|
||||
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/dashboard.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/dashboard.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<link rel="stylesheet" href="/pos/static/css/onboarding.css" />
|
||||
<link rel="manifest" href="/pos/static/pwa/manifest.json" />
|
||||
<meta name="theme-color" content="#F5A623" />
|
||||
<script src="/pos/static/js/native-bridge.js"></script>
|
||||
<script src="/pos/static/js/native-bridge.js" defer></script>
|
||||
|
||||
<style>
|
||||
/* =========================================================================
|
||||
@@ -604,12 +604,12 @@
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/kiosk.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/diagrams.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/kiosk.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/diagrams.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -963,12 +963,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/fleet.js"></script>
|
||||
<script src="/pos/static/js/offline-banner.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/fleet.js" defer></script>
|
||||
<script src="/pos/static/js/offline-banner.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -2106,13 +2106,13 @@
|
||||
<button class="banner__dismiss" onclick="document.getElementById('offlineBanner').style.display='none'" aria-label="Cerrar">×</button>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/inventory.js"></script>
|
||||
<script src="/pos/static/js/offline-banner.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/inventory.js" defer></script>
|
||||
<script src="/pos/static/js/offline-banner.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2386,12 +2386,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/invoicing.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/invoicing.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -1362,8 +1362,8 @@
|
||||
|
||||
</script>
|
||||
|
||||
<script src="/pos/static/js/kiosk.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/kiosk.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<link rel="stylesheet" href="/pos/static/css/chat.css" />
|
||||
<link rel="manifest" href="/pos/static/pwa/manifest.json" />
|
||||
<meta name="theme-color" content="#F5A623" />
|
||||
<script src="/pos/static/js/native-bridge.js"></script>
|
||||
<script src="/pos/static/js/native-bridge.js" defer></script>
|
||||
|
||||
<style>
|
||||
/* =====================================================================
|
||||
@@ -1480,13 +1480,13 @@
|
||||
<!-- ================================================================
|
||||
JAVASCRIPT
|
||||
================================================================ -->
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/kiosk.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/push.js"></script>
|
||||
<script src="/pos/static/js/printer.js"></script>
|
||||
<script src="/pos/static/js/pos.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/kiosk.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/push.js" defer></script>
|
||||
<script src="/pos/static/js/printer.js" defer></script>
|
||||
<script src="/pos/static/js/pos.js" defer></script>
|
||||
|
||||
<script>
|
||||
// Cancel sale button wiring
|
||||
@@ -1539,8 +1539,8 @@
|
||||
setInterval(updateClock, 30000);
|
||||
</script>
|
||||
|
||||
<script src="/pos/static/js/chat.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/chat.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
|
||||
<div class="page">
|
||||
<h1 class="page-title">Cotizaciones</h1>
|
||||
|
||||
@@ -1847,12 +1847,12 @@
|
||||
</div>
|
||||
<!-- End app-shell -->
|
||||
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/reports.js"></script>
|
||||
<script src="/pos/static/js/sync-engine.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
<script src="/pos/static/js/reports.js" defer></script>
|
||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -628,10 +628,10 @@ function posLogout(){localStorage.removeItem('pos_token');window.location.href='
|
||||
</script>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<script src="/pos/static/js/i18n.js"></script>
|
||||
<script src="/pos/static/js/whatsapp.js"></script>
|
||||
<script src="/pos/static/js/pos-utils.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/i18n.js" defer></script>
|
||||
<script src="/pos/static/js/whatsapp.js" defer></script>
|
||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user