major update

This commit is contained in:
naielv
2025-12-12 19:13:53 +01:00
parent cca21ac3d3
commit 60a7649c36
28 changed files with 917 additions and 854 deletions

View File

@@ -1,46 +0,0 @@
name: Build and publish clients
on:
push:
tags:
- "v*.*.*"
jobs:
build-windows:
permissions:
contents: write
name: Build EXE
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: "Build Files"
run: "python3 build.py 'TeleSec para Windows'"
- name: Create Executable
uses: sayyid5416/pyinstaller@v1
with:
python_ver: "3.11"
spec: "WinApp.spec"
requirements: "requirements.txt"
upload_exe_with_name: "TeleSec_Windows"
release:
needs:
- build-windows
name: Release via GHA
runs-on: ubuntu-latest
if: startsWith(github.ref_name, 'v')
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
name: TeleSec_Windows
- uses: ncipollo/release-action@v1
with:
artifacts: "TeleSec para Windows.exe"
prerelease: true
allowUpdates: true
omitBodyDuringUpdate: true
omitPrereleaseDuringUpdate: true

View File

@@ -34,7 +34,7 @@ jobs:
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Build
run: python3 build.py
run: TELESEC_HOSTER=GitHub-Pages python3 build.py
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:

View File

@@ -1,39 +0,0 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
["main.py"],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name="TeleSec",
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=["favicon.ico"],
)

View File

@@ -1,18 +0,0 @@
{
"theme_color":"#23365e",
"background_color":"#ffffff",
"icons":[
{"purpose":"maskable","sizes":"512x512","src":"icon512_maskable.png","type":"image/png"},
{"purpose":"any","sizes":"512x512","src":"icon512_rounded.png","type":"image/png"}
],
"orientation":"portrait",
"display":"standalone",
"dir":"auto",
"lang":"es-ES",
"start_url":"index.html",
"scope":"/",
"description":"La app de TeleSec",
"id":"telesec.tech.eus",
"name": "TeleSec",
"short_name": "TeleSec"
}

View File

@@ -348,10 +348,11 @@ hr {
align-items: center;
padding: 0 5px;
border-radius: 3px 3px 0 0;
overflow-x: auto;
}
.ribbon-tab {
padding: 4px 15px;
padding: 4px 9px;
cursor: pointer;
border-right: 1px solid #a2a9b9;
font-size: 13px;
@@ -367,7 +368,7 @@ hr {
gap: 10px;
background-color: #c8d4eb;
border: 1px solid #a2a9b9;
overflow-x: scroll;
overflow-x: auto;
padding: 5px;
}

View File

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 185 KiB

View File

@@ -16,7 +16,8 @@ def get_all_files(directory):
PREFETCH = ""
VERSIONCO = "2025-08"
HANDLEPARSE = get_all_files("src")
TITLE = os.environ.get("TELESEC_TITLE", "TeleSec")
HOSTER = os.environ.get("TELESEC_HOSTER", "EuskadiTech")
# Combine assets from JSON and recursively found files
ASSETS = get_all_files("assets")
@@ -35,6 +36,7 @@ def replace_handles(string):
string = string.replace("%%PREFETCH%%", PREFETCH)
string = string.replace("%%VERSIONCO%%", VERSIONCO)
string = string.replace("%%TITLE%%", "TeleSec")
string = string.replace("%%HOSTER%%", HOSTER)
string = string.replace("%%ASSETSJSON%%", json.dumps(ASSETS, ensure_ascii=False))
return string

View File

@@ -1,6 +0,0 @@
import webview
import sys
if __name__ == '__main__':
webview.create_window('TeleSec', url="https://telesec.tech.eus/")
webview.start()

View File

@@ -1 +1 @@
pywebview
requests

File diff suppressed because it is too large Load Diff

View File

@@ -3,14 +3,14 @@ var EventListeners = {
Timeout: [],
Interval: [],
QRScanner: [],
}
};
var urlParams = new URLSearchParams(location.search);
var AC_BYPASS = false;
if (urlParams.get("ac_bypass") == "yes") {
AC_BYPASS = true;
}
if (urlParams.get("hidenav") != undefined){
document.getElementById("header_hide_query").style.display = "none"
if (urlParams.get("hidenav") != undefined) {
document.getElementById("header_hide_query").style.display = "none";
}
var GROUPID = "";
// const PUBLIC_KEY = "~cppGiuA4UFUPGTDoC-4r2izVC3F7MfpaCmF3iZdESN4.vntmjgbAVUpF_zfinYY6EKVFuuTYxh5xOrL4KmtdTmc"
@@ -38,13 +38,21 @@ var SECRET = "";
var SUB_LOGGED_IN = false;
var SUB_LOGGED_IN_DETAILS = false;
var SUB_LOGGED_IN_ID = false;
var SAVE_WAIT = 500;
var SC_Personas = {};
var PeerConnectionInterval = 5000;
if (urlParams.get("sublogin") != null) {
SUB_LOGGED_IN = true;
SUB_LOGGED_IN_ID = urlParams.get("sublogin");
SUB_LOGGED_IN_DETAILS = true;
setInterval(() => {
SUB_LOGGED_IN_DETAILS = SC_Personas[SUB_LOGGED_IN_ID];
var sli = 15;
var slii = setInterval(() => {
SUB_LOGGED_IN_DETAILS = SC_Personas[SUB_LOGGED_IN_ID];
}, 7500);
sli-=1;
if (sli < 0) {
clearInterval(slii);
}
}, 500);
}
function LogOutTeleSec() {
SUB_LOGGED_IN = false;
@@ -55,4 +63,4 @@ function LogOutTeleSec() {
urlParams.delete("sublogin");
history.replaceState(null, "", "?" + urlParams.toString());
location.reload();
}
}

View File

@@ -2,7 +2,7 @@ window.rtcRoom = "telesec.tech.eus";
var opt = {
axe: false,
localStorage: false,
peers: RELAYS
peers: RELAYS,
// radisk: true,
};
@@ -40,8 +40,10 @@ function formatPeerInfo(peer) {
}
function isPeerConnected(peer) {
return peer.wire != undefined &&
(peer.wire.readyState == 1 || peer.wire.readyState == "open");
return (
peer.wire != undefined &&
(peer.wire.readyState == 1 || peer.wire.readyState == "open")
);
}
function createPeerListElement(wireHType, wireID) {
@@ -53,21 +55,21 @@ function createPeerListElement(wireHType, wireID) {
function updateConnectionStatus(peerCount) {
var statusImage = peerCount < 1 ? "connect_ko.svg" : "connect_ok.svg";
if (window.navigator.onLine == false) {
statusImage = "offline.svg"
statusImage = "offline.svg";
}
document.getElementById("connectStatus").src = `static/ico/${statusImage}`;
if (peerCount < 1) {
if (!window.peerRetryCount) window.peerRetryCount = 0;
window.peerRetryCount = (window.peerRetryCount + 1) % 3;
if (window.peerRetryCount === 0) {
gun.opt({ peers: RELAYS });
// Enhanced peer connection retry
setTimeout(() => {
gun.opt({ peers: RELAYS });
}, 1000);
setTimeout(() => {
gun.opt({ peers: RELAYS });
}, 3000);
@@ -76,9 +78,9 @@ function updateConnectionStatus(peerCount) {
} else {
ConnectionStarted = true;
AtLeastThreePeers = true;
// When we have good connectivity, force a data refresh
if (typeof refreshAllData === 'function') {
if (typeof refreshAllData === "function") {
setTimeout(refreshAllData, 1000);
}
}
@@ -88,22 +90,22 @@ function getPeers() {
const peerCountEl = document.getElementById("peerCount");
const peerListEl = document.getElementById("peerList");
const list = document.createElement("ul");
document.getElementById("peerPID").innerText = "PID " + gun.back("opt.pid");
const connectedPeers = Object.values(gun.back("opt.peers"))
.filter(isPeerConnected)
.map(peer => {
.map((peer) => {
const { wireHType, wireID } = formatPeerInfo(peer);
return createPeerListElement(wireHType, wireID);
});
connectedPeers.forEach(el => list.append(el));
connectedPeers.forEach((el) => list.append(el));
peerListEl.innerHTML = list.innerHTML;
const peerCount = connectedPeers.length;
peerCountEl.innerText = peerCount;
updateConnectionStatus(peerCount);
}
function safeuuid(prefix = "AXLUID_") {

View File

@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="manifest" href="manifest.json" />
<title>%%TITLE%%</title>
<link rel="icon" type="image/png" href="static/TeleSec.jpg" />
<link rel="icon" type="image/png" href="static/logo.jpg" />
<link href="static/euskaditech-css/simple.css" rel="stylesheet" />
<link href="static/toastr.min.css" rel="stylesheet" />
%%PREFETCH%%
@@ -19,7 +19,7 @@
<div class="ribbon-content">
<div class="ribbon-tabs">
<div class="ribbon-tab active" data-tab="modulos">Modulos</div>
<div class="ribbon-tab" data-tab="buscar">🔍 Buscar</div>
<div class="ribbon-tab" data-tab="buscar">Buscar</div>
<div class="ribbon-tab" data-tab="credenciales">Credenciales</div>
</div>
@@ -56,7 +56,7 @@
Iniciar sesión
</button><br>
<b>Conectado a <span id="peerCount">?</span>
nodos</b>
nodos - proveedor %%HOSTER%%</b>
</div>
</div>
</details>
@@ -86,7 +86,7 @@
display: none;
" />
<div id="snackbar">
Hay una nueva versión de TeleSec.<br /><a id="reload">Pulsa aqui para actualizar.</a>
Hay una nueva versión de %%TITLE%%.<br /><a id="reload">Pulsa aqui para actualizar.</a>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js" integrity="sha256-/H4YS+7aYb9kJ5OKhFYPUjSJdrtV6AeyJOtTkw6X72o=" crossorigin="anonymous"></script>
<script src="static/showdown.min.js"></script>
@@ -122,10 +122,10 @@
<script src="page/resumen_diario.js"></script>
<script src="page/personas.js"></script>
<script src="page/supercafe.js"></script>
<script src="page/avisos.js"></script>
<!-- <script src="page/avisos.js"></script> -->
<script src="page/comedor.js"></script>
<script src="page/notas.js"></script>
<script src="page/chat.js"></script>
<!-- <script src="page/chat.js"></script> -->
<script src="page/buscar.js"></script>
<script src="page/pagos.js"></script>
</body>

28
src/manifest.json Normal file
View File

@@ -0,0 +1,28 @@
{
"theme_color": "#23365e",
"background_color": "#ffffff",
"icons": [
{
"purpose": "maskable",
"sizes": "512x512",
"src": "icon512_maskable.png",
"type": "image/png"
},
{
"purpose": "any",
"sizes": "512x512",
"src": "icon512_rounded.png",
"type": "image/png"
}
],
"orientation": "portrait",
"display": "standalone",
"dir": "auto",
"lang": "es-ES",
"start_url": "index.html",
"scope": "/",
"description": "%%TITLE%% - Comunicación Hipersegura",
"id": "telesec.tech.eus",
"name": "%%TITLE%%",
"short_name": "%%TITLE%%"
}

View File

@@ -230,7 +230,7 @@ PAGES.aulas = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("aulas,solicitudes");
}, 750);
}, SAVE_WAIT);
});
};
document.getElementById(btn_borrar).onclick = () => {
@@ -239,7 +239,7 @@ PAGES.aulas = {
toastr.error("Borrado!");
setTimeout(() => {
setUrlHash("aulas,solicitudes");
}, 750);
}, SAVE_WAIT);
}
};
},
@@ -310,27 +310,27 @@ PAGES.aulas = {
title = "Diario " + date[2] + "/" + date[1] + "/" + date[0];
}
container.innerHTML = `
<a class="button" href="#aulas,informes">← Volver a informes</a>
<h1>Informe <code id="${nameh1}"></code></h1>
<fieldset style="float: none; width: calc(100% - 40px);max-width: none;">
<legend>Valores</legend>
<div style="max-width: 400px;">
<label>
Asunto<br>
<input type="text" id="${field_asunto}" value=""><br><br>
</label>
<input type="hidden" id="${field_autor}" readonly value="">
<input type="hidden" id="${field_fecha}" value="">
</div>
<a class="button" href="#aulas,informes">← Volver a informes</a>
<h1>Informe <code id="${nameh1}"></code></h1>
<fieldset style="float: none; width: calc(100% - 40px);max-width: none;">
<legend>Valores</legend>
<div style="max-width: 400px;">
<label>
Contenido<br>
<textarea id="${field_contenido}" style="width: 100%; height: 400px;"></textarea><br><br>
Asunto<br>
<input type="text" id="${field_asunto}" value=""><br><br>
</label>
<hr>
<button class="btn5" id="${btn_guardar}">Guardar</button>
<button class="rojo" id="${btn_borrar}">Borrar</button>
</fieldset>
`;
<input type="hidden" id="${field_autor}" readonly value="">
<input type="hidden" id="${field_fecha}" value="">
</div>
<label>
Contenido<br>
<textarea id="${field_contenido}" style="width: 100%; height: 400px;"></textarea><br><br>
</label>
<hr>
<button class="btn5" id="${btn_guardar}">Guardar</button>
<button class="rojo" id="${btn_borrar}">Borrar</button>
</fieldset>
`;
gun
.get(TABLE)
.get("aulas_informes")
@@ -366,7 +366,7 @@ PAGES.aulas = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("aulas,informes");
}, 750);
}, SAVE_WAIT);
});
};
document.getElementById(btn_borrar).onclick = () => {
@@ -375,7 +375,7 @@ PAGES.aulas = {
toastr.error("Borrado!");
setTimeout(() => {
setUrlHash("aulas,informes");
}, 750);
}, SAVE_WAIT);
}
};
},

View File

@@ -4,7 +4,6 @@ PAGES.avisos = {
navcss: "btn5",
icon: "static/appico/File_Plugin.svg",
AccessControl: true,
Esconder: true,
Title: "Avisos",
edit: function (mid) {
if (!checkRole("avisos:edit")) {setUrlHash("avisos");return}
@@ -22,40 +21,40 @@ PAGES.avisos = {
var btn_borrar = safeuuid();
var div_actions = safeuuid();
container.innerHTML = `
<h1>Aviso <code id="${nameh1}"></code></h1>
<fieldset style="float: left;">
<legend>Valores</legend>
<label>
Fecha<br>
<input readonly disabled type="text" id="${field_fecha}" value=""><br><br>
</label>
<label>
Asunto<br>
<input type="text" id="${field_asunto}" value=""><br><br>
</label>
<input type="hidden" id="${field_origen}">
<input type="hidden" id="${field_destino}">
<div id="${div_actions}"></div>
<label>
Mensaje<br>
<textarea id="${field_mensaje}"></textarea><br><br>
</label>
<label>
Respuesta<br>
<textarea id="${field_respuesta}"></textarea><br><br>
</label>
<label>
Estado<br>
<input readonly disabled type="text" id="${field_estado}" value="">
<br>
<button id="${btn_leer}">Leido</button>
<button id="${btn_desleer}">No leido</button>
<br>
</label><hr>
<button class="btn5" id="${btn_guardar}">Guardar</button>
<button class="rojo" id="${btn_borrar}">Borrar</button>
</fieldset>
`;
<h1>Aviso <code id="${nameh1}"></code></h1>
<fieldset style="float: left;">
<legend>Valores</legend>
<label>
Fecha<br>
<input readonly disabled type="text" id="${field_fecha}" value=""><br><br>
</label>
<label>
Asunto<br>
<input type="text" id="${field_asunto}" value=""><br><br>
</label>
<input type="hidden" id="${field_origen}">
<input type="hidden" id="${field_destino}">
<div id="${div_actions}"></div>
<label>
Mensaje<br>
<textarea id="${field_mensaje}"></textarea><br><br>
</label>
<label>
Respuesta<br>
<textarea id="${field_respuesta}"></textarea><br><br>
</label>
<label>
Estado<br>
<input readonly disabled type="text" id="${field_estado}" value="">
<br>
<button id="${btn_leer}">Leido</button>
<button id="${btn_desleer}">No leido</button>
<br>
</label><hr>
<button class="btn5" id="${btn_guardar}">Guardar</button>
<button class="rojo" id="${btn_borrar}">Borrar</button>
</fieldset>
`;
document.getElementById(btn_leer).onclick = () => {
document.getElementById(field_estado).value = "leido";
};
@@ -158,7 +157,7 @@ PAGES.avisos = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("avisos");
}, 750);
}, SAVE_WAIT);
});
};
document.getElementById(btn_borrar).onclick = () => {
@@ -167,7 +166,7 @@ PAGES.avisos = {
toastr.error("Borrado!");
setTimeout(() => {
setUrlHash("avisos");
}, 750);
}, SAVE_WAIT);
}
};
},
@@ -176,10 +175,10 @@ PAGES.avisos = {
const tablebody = safeuuid();
var btn_new = safeuuid();
container.innerHTML = `
<h1>Avisos</h1>
<button id="${btn_new}">Nuevo aviso</button>
<div id="cont"></div>
`;
<h1>Avisos</h1>
<button id="${btn_new}">Nuevo aviso</button>
<div id="cont"></div>
`;
TS_IndexElement(
"avisos",
[

View File

@@ -4,14 +4,14 @@ PAGES.buscar = {
Title: "Buscar",
AccessControl: true,
Esconder: true,
index: function() {
index: function () {
const searchInput = safeuuid();
const resultsContainer = safeuuid();
const searchButton = safeuuid();
const recentSearches = safeuuid();
const moduleFilter = safeuuid();
container.innerHTML = `
<h1>🔍 Búsqueda Global</h1>
<p>Busca en todos los módulos: personas, materiales, café, comedor, notas y avisos</p>
@@ -51,60 +51,66 @@ PAGES.buscar = {
</fieldset>
</div>
`;
// Initialize global search
const globalSearch = GlobalSearch();
globalSearch.loadAllData();
// Get accessible modules for the current user
const accessibleModules = globalSearch.getAccessibleModules();
const searchInputEl = document.getElementById(searchInput);
const resultsEl = document.getElementById(resultsContainer);
const searchButtonEl = document.getElementById(searchButton);
const recentSearchesEl = document.getElementById(recentSearches);
const moduleFilterEl = document.getElementById(moduleFilter);
// Populate module filter dropdown with only accessible modules
function populateModuleFilter() {
// Clear existing options except "Todos los módulos"
moduleFilterEl.innerHTML = '<option value="">Todos los módulos</option>';
// Add only accessible modules
accessibleModules.forEach(module => {
const option = document.createElement('option');
accessibleModules.forEach((module) => {
const option = document.createElement("option");
option.value = module.key;
option.textContent = `${getModuleIcon(module.key)} ${module.title}`;
moduleFilterEl.appendChild(option);
});
}
// Helper function to get module icons (fallback for older module mappings)
function getModuleIcon(moduleKey) {
const iconMap = {
'personas': '👤',
'materiales': '📦',
'supercafe': '☕',
'comedor': '🍽️',
'avisos': '🔔',
'aulas': '🏫',
'resumen_diario': '📊'
personas: "👤",
materiales: "📦",
supercafe: "☕",
comedor: "🍽️",
avisos: "🔔",
aulas: "🏫",
resumen_diario: "📊",
};
return iconMap[moduleKey] || '📋';
return iconMap[moduleKey] || "📋";
}
// Load recent searches from localStorage
function loadRecentSearches() {
const recent = JSON.parse(localStorage.getItem('telesec_recent_searches') || '[]');
const recent = JSON.parse(
localStorage.getItem("telesec_recent_searches") || "[]"
);
if (recent.length > 0) {
recentSearchesEl.innerHTML = `
<fieldset>
<legend>Búsquedas recientes</legend>
${recent.map(term => `
${recent
.map(
(term) => `
<button onclick="document.getElementById('${searchInput}').value='${term}'; document.getElementById('${searchButton}').click();" class="btn4">
${term}
</button>
`).join('')}
`
)
.join("")}
<button onclick="localStorage.removeItem('telesec_recent_searches'); this.parentElement.style.display='none';" class="rojo">
Limpiar
</button>
@@ -112,28 +118,30 @@ PAGES.buscar = {
`;
}
}
// Populate the module filter dropdown
populateModuleFilter();
// Save search term to recent searches
function saveToRecent(term) {
if (!term || term.length < 2) return;
let recent = JSON.parse(localStorage.getItem('telesec_recent_searches') || '[]');
recent = recent.filter(t => t !== term); // Remove if exists
let recent = JSON.parse(
localStorage.getItem("telesec_recent_searches") || "[]"
);
recent = recent.filter((t) => t !== term); // Remove if exists
recent.unshift(term); // Add to beginning
recent = recent.slice(0, 5); // Keep only 5 most recent
localStorage.setItem('telesec_recent_searches', JSON.stringify(recent));
localStorage.setItem("telesec_recent_searches", JSON.stringify(recent));
loadRecentSearches();
}
// Perform search
function performSearch() {
const searchTerm = searchInputEl.value.trim();
const selectedModule = moduleFilterEl.value;
if (searchTerm.length < 2) {
resultsEl.innerHTML = `
<fieldset>
@@ -143,7 +151,7 @@ PAGES.buscar = {
`;
return;
}
// Show loading
resultsEl.innerHTML = `
<fieldset>
@@ -151,46 +159,50 @@ PAGES.buscar = {
<div>⏳ Procesando búsqueda...</div>
</fieldset>
`;
// Add small delay to show loading state
setTimeout(() => {
let results = globalSearch.performSearch(searchTerm);
// Filter by module if selected
if (selectedModule) {
results = results.filter(result => result._module === selectedModule);
results = results.filter(
(result) => result._module === selectedModule
);
}
globalSearch.renderResults(results, resultsEl);
saveToRecent(searchTerm);
// Add stats
if (results.length > 0) {
const statsDiv = document.createElement('fieldset');
const legend = document.createElement('legend');
legend.textContent = 'Estadísticas';
const statsDiv = document.createElement("fieldset");
const legend = document.createElement("legend");
legend.textContent = "Estadísticas";
statsDiv.appendChild(legend);
let filterText = selectedModule ? ` en ${moduleFilterEl.options[moduleFilterEl.selectedIndex].text}` : '';
const content = document.createElement('div');
let filterText = selectedModule
? ` en ${moduleFilterEl.options[moduleFilterEl.selectedIndex].text}`
: "";
const content = document.createElement("div");
content.innerHTML = `📊 Se encontraron <strong>${results.length}</strong> resultados para "<strong>${searchTerm}</strong>"${filterText}`;
statsDiv.appendChild(content);
resultsEl.insertBefore(statsDiv, resultsEl.firstChild);
}
}, 500);
}
// Event listeners
searchButtonEl.onclick = performSearch;
// Filter change listener
moduleFilterEl.onchange = () => {
if (searchInputEl.value.trim().length >= 2) {
performSearch();
}
};
// Auto-search as user types (with debounce)
let searchTimeout;
searchInputEl.oninput = () => {
@@ -201,22 +213,22 @@ PAGES.buscar = {
}
}, 1501);
};
// Focus on search input
searchInputEl.focus();
// Add keyboard shortcuts
document.addEventListener('keydown', function(e) {
document.addEventListener("keydown", function (e) {
// Ctrl+F or Cmd+F to focus search
if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
if ((e.ctrlKey || e.metaKey) && e.key === "f") {
e.preventDefault();
searchInputEl.focus();
searchInputEl.select();
}
// Escape to clear search
if (e.key === 'Escape') {
searchInputEl.value = '';
if (e.key === "Escape") {
searchInputEl.value = "";
searchInputEl.focus();
resultsEl.innerHTML = `
<fieldset>
@@ -238,17 +250,17 @@ PAGES.buscar = {
`;
}
});
// Check for quick search term from header
const quickSearchTerm = sessionStorage.getItem('telesec_quick_search');
const quickSearchTerm = sessionStorage.getItem("telesec_quick_search");
if (quickSearchTerm) {
searchInputEl.value = quickSearchTerm;
sessionStorage.removeItem('telesec_quick_search');
sessionStorage.removeItem("telesec_quick_search");
// Perform search automatically
setTimeout(performSearch, 100);
}
// Load recent searches
loadRecentSearches();
}
},
};

View File

@@ -15,17 +15,17 @@ PAGES.comedor = {
container.innerHTML = `
<h1>Entrada del menú <code id="${nameh1}"></code></h1>
<fieldset style="float: left;">
<legend>Valores</legend>
<label>
Fecha<br>
<input type="date" id="${field_fecha}" value=""><br><br>
</label>
<label>
Platos<br>
<textarea id="${field_platos}"></textarea><br><br>
</label>
<button class="btn5" id="${btn_guardar}">Guardar</button>
<button class="rojo" id="${btn_borrar}">Borrar</button>
<legend>Valores</legend>
<label>
Fecha<br>
<input type="date" id="${field_fecha}" value=""><br><br>
</label>
<label>
Platos<br>
<textarea id="${field_platos}"></textarea><br><br>
</label>
<button class="btn5" id="${btn_guardar}">Guardar</button>
<button class="rojo" id="${btn_borrar}">Borrar</button>
</fieldset>
`;
gun
@@ -66,7 +66,7 @@ PAGES.comedor = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("comedor");
}, 750);
}, SAVE_WAIT);
});
};
document.getElementById(btn_borrar).onclick = () => {
@@ -75,19 +75,19 @@ PAGES.comedor = {
toastr.error("Borrado!");
setTimeout(() => {
setUrlHash("comedor");
}, 750);
}, SAVE_WAIT);
}
};
},
index: function () {
if (!checkRole("comedor")) {setUrlHash("index");return}
const tablebody = safeuuid();
const cont = safeuuid();
var btn_new = safeuuid();
container.innerHTML = `
<h1>Menú del comedor</h1>
<button id="${btn_new}">Nueva entrada</button>
<div id="cont"></div>
`;
<h1>Menú del comedor</h1>
<button id="${btn_new}">Nueva entrada</button>
<div id="${cont}"></div>
`;
TS_IndexElement(
"comedor",
[
@@ -105,7 +105,7 @@ PAGES.comedor = {
}
],
gun.get(TABLE).get("comedor"),
document.querySelector("#cont"),
document.getElementById(cont),
(data, new_tr) => {
// new_tr.style.backgroundColor = "#FFCCCB";
if (data.Fecha == CurrentISODate()) {

View File

@@ -52,16 +52,16 @@ PAGES.dataman = {
container.innerHTML = `
<h1>Exportar Datos</h1>
<fieldset>
<legend>Exportar datos</legend>
<em>Al pulsar, Espera hasta que salga una notificacion verde.</em>
<br>
<br>
<button id="${button_export_local}" type="button">Exportar sin cifrar</button>
<button id="${button_export_safe}" type="button">Exportar con cifrado</button>
<button id="${button_export_safe_cloud}" style="display: none;" type="button">Exportar a EuskadiTech - cifrado</button>
<!--<br><br><em>Para descargar envia un correo a telesec@tech.eus con el asunto "TSBK %${GROUPID}".</em>-->
<legend>Exportar datos</legend>
<em>Al pulsar, Espera hasta que salga una notificacion verde.</em>
<br>
<br>
<button id="${button_export_local}" type="button">Exportar sin cifrar</button>
<button id="${button_export_safe}" type="button">Exportar con cifrado</button>
<button id="${button_export_safe_cloud}" style="display: none;" type="button">Exportar a EuskadiTech - cifrado</button>
<!--<br><br><em>Para descargar envia un correo a telesec@tech.eus con el asunto "TSBK %${GROUPID}".</em>-->
</fieldset>
`;
`;
document.getElementById(button_export_local).onclick = () => {
var data_export = {};
var output = {
@@ -85,7 +85,7 @@ PAGES.dataman = {
});
toastr.success("Exportado todo, descargando!");
download(
`Export TeleSec ${GROUPID}.json.txt`,
`Export %%TITLE%% ${GROUPID}.json.txt`,
JSON.stringify(output)
);
//setUrlHash(sel);
@@ -97,32 +97,32 @@ PAGES.dataman = {
var download_data = (DATA) => {
toastr.success("Exportado todo, descargado!");
download(
`Export TeleSec Encriptado ${GROUPID}.json.txt`,
`Export %%TITLE%% Encriptado ${GROUPID}.json.txt`,
JSON.stringify(DATA)
);
//setUrlHash(sel);
};
gun.get(TABLE).load(download_data);
};
document.getElementById(button_export_safe_cloud).onclick = () => {
var download_data = (DATA) => {
toastr.info("Exportado todo, subiendo!");
fetch(
"https://telesec-sync.tech.eus/upload_backup.php?table=" + GROUPID,
{
method: "POST",
body: JSON.stringify(DATA),
}
)
.then(() => {
toastr.success("Subido correctamente!");
})
.catch(() => {
toastr.error("Ha ocurrido un error en la subida.");
});
};
gun.get(TABLE).load(download_data);
};
// document.getElementById(button_export_safe_cloud).onclick = () => {
// var download_data = (DATA) => {
// toastr.info("Exportado todo, subiendo!");
// fetch(
// "https://telesec-sync.tech.eus/upload_backup.php?table=" + GROUPID,
// {
// method: "POST",
// body: JSON.stringify(DATA),
// }
// )
// .then(() => {
// toastr.success("Subido correctamente!");
// })
// .catch(() => {
// toastr.error("Ha ocurrido un error en la subida.");
// });
// };
// gun.get(TABLE).load(download_data);
// };
},
__import: function () {
var select_type = safeuuid();

View File

@@ -4,10 +4,11 @@ PAGES.index = {
index: function() {
container.innerHTML = `
<h1>¡Hola, ${SUB_LOGGED_IN_DETAILS.Nombre}!<br>Bienvenidx a %%TITLE%%</h1>
<h2>Tienes ${parseFloat(SUB_LOGGED_IN_DETAILS.Monedero_Balance).toString()} € en el monedero.</h2>
<em>Utiliza el menú superior para abrir un modulo</em>
<br><br>
<button class="btn1" onclick="LogOutTeleSec()">Cerrar sesión</button>
`;
`;
},
edit: function(mid) {
switch (mid) {

View File

@@ -15,16 +15,16 @@ PAGES.login = {
var btn_reload = safeuuid();
var div_actions = safeuuid();
container.innerHTML = `
<h1>Iniciar sesión</h1>
<fieldset>
<legend>Valores</legend>
<input type="hidden" id="${field_persona}">
<div id="${div_actions}"></div>
<button class="btn5" id="${btn_guardar}">Acceder</button>
<button class="btn1" id="${btn_reload}">Recargar lista</button>
</fieldset>
<a href="#login,setup">Empezar desde cero</a>
`;
<h1>Iniciar sesión</h1>
<fieldset>
<legend>Valores</legend>
<input type="hidden" id="${field_persona}">
<div id="${div_actions}"></div>
<button class="btn5" id="${btn_guardar}">Acceder</button>
<button class="btn1" id="${btn_reload}">Recargar lista</button>
</fieldset>
<a href="#login,setup">Empezar desde cero</a>
`;
var divact = document.getElementById(div_actions);
addCategory_Personas(
divact,

View File

@@ -12,7 +12,6 @@ PAGES.materiales = {
var field_cantidad = safeuuid();
var field_unidad = safeuuid();
var field_cantidad_min = safeuuid();
var field_abierto = safeuuid();
var field_ubicacion = safeuuid();
var field_referencia = safeuuid();
var field_notas = safeuuid();
@@ -98,7 +97,7 @@ PAGES.materiales = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("materiales");
}, 750);
}, SAVE_WAIT);
});
};
document.getElementById(btn_borrar).onclick = () => {
@@ -107,7 +106,7 @@ PAGES.materiales = {
toastr.error("Borrado!");
setTimeout(() => {
setUrlHash("materiales");
}, 750);
}, SAVE_WAIT);
}
};
},
@@ -115,6 +114,7 @@ PAGES.materiales = {
if (!checkRole("materiales")) {setUrlHash("index");return}
var btn_new = safeuuid();
var select_ubicacion = safeuuid();
var tableContainer = safeuuid();
container.innerHTML = `
<h1>Materiales</h1>
<label>Filtrar por ubicación:
@@ -123,7 +123,7 @@ PAGES.materiales = {
</select>
</label>
<button id="${btn_new}">Nuevo Material</button>
<div id="tableContainer"></div>
<div id="${tableContainer}"></div>
`;
const config = [
@@ -190,7 +190,7 @@ PAGES.materiales = {
"materiales",
config,
gun.get(TABLE).get("materiales"),
document.getElementById("tableContainer"),
document.getElementById(tableContainer),
function(data, new_tr) {
if (parseFloat(data.Cantidad) < parseFloat(data.Cantidad_Minima)) {
new_tr.style.background = "lightcoral"

View File

@@ -1,10 +1,10 @@
PERMS["notas"] = "Notas"
PERMS["notas"] = "Noticias"
PERMS["notas:edit"] = "&gt; Editar"
PAGES.notas = {
navcss: "btn5",
icon: "static/appico/Notepad.svg",
icon: "static/appico/Newspaper.svg",
AccessControl: true,
Title: "Notas",
Title: "Noticias",
edit: function (mid) {
if (!checkRole("notas:edit")) {setUrlHash("notas");return}
var nameh1 = safeuuid();
@@ -15,7 +15,7 @@ PAGES.notas = {
var btn_borrar = safeuuid();
var div_actions = safeuuid();
container.innerHTML = `
<h1>Nota <code id="${nameh1}"></code></h1>
<h1>Noticia <code id="${nameh1}"></code></h1>
<fieldset style="float: none; width: calc(100% - 40px);max-width: none;">
<legend>Valores</legend>
<div style="max-width: 400px;">
@@ -28,7 +28,7 @@ PAGES.notas = {
</div>
<label>
Contenido<br>
<textarea id="${field_contenido}" style="width: 100%; height: 400px;"></textarea><br><br>
<textarea id="${field_contenido}" style="width: calc(100% - 15px); height: 400px;"></textarea><br><br>
</label>
<hr>
<button class="btn5" id="${btn_guardar}">Guardar</button>
@@ -62,7 +62,7 @@ PAGES.notas = {
addCategory_Personas(
divact,
SC_Personas,
data["Autor"] || "",
data["Autor"] || SUB_LOGGED_IN_ID || "",
(value) => {
document.getElementById(field_autor).value = value;
},
@@ -93,7 +93,7 @@ PAGES.notas = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("notas");
}, 750);
}, SAVE_WAIT);
});
};
document.getElementById(btn_borrar).onclick = () => {
@@ -102,7 +102,7 @@ PAGES.notas = {
toastr.error("Borrado!");
setTimeout(() => {
setUrlHash("notas");
}, 750);
}, SAVE_WAIT);
}
};
},
@@ -111,8 +111,8 @@ PAGES.notas = {
const tablebody = safeuuid();
var btn_new = safeuuid();
container.innerHTML = `
<h1>Notas</h1>
<button id="${btn_new}">Nueva nota</button>
<h1>Noticias</h1>
<button id="${btn_new}">Nueva noticia</button>
<div id="cont"></div>
`;
TS_IndexElement(

View File

@@ -51,7 +51,7 @@ PAGES.pagos = {
container.innerHTML = `
<div style="max-width: 600px; margin: 0 auto; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3);">
<h1 style="color: white; text-align: center; margin-bottom: 20px;">
Terminal de pago TeleSec
Terminal de pago %%TITLE%%
</h1>
<div style="margin: 0 auto;max-width: 435px;background: white;padding: 20px;border-radius: 10px;margin-bottom: 20px;">
@@ -268,6 +268,19 @@ PAGES.pagos = {
}
}
// Check if persona has enough balance for Gasto or Transferencia
if (tipo === 'Gasto' || tipo === 'Transferencia') {
if (metodo == "Tarjeta") {
var persona = SC_Personas[personaId];
var currentBalance = parseFloat(persona.Monedero_Balance || 0);
if (currentBalance < monto) {
if (!confirm(`Saldo insuficiente (${currentBalance.toFixed(2)}€). ¿Continuar de todos modos?`)) {
return;
}
}
}
}
// Move to step 3 - confirmation
document.getElementById('step2').style.display = 'none';
document.getElementById('step3').style.display = 'block';
@@ -393,19 +406,6 @@ PAGES.pagos = {
}
}
// Check if persona has enough balance for Gasto or Transferencia
if (tipo === 'Gasto' || tipo === 'Transferencia') {
if (metodo == "Tarjeta") {
var persona = SC_Personas[personaId];
var currentBalance = parseFloat(persona.Monedero_Balance || 0);
if (currentBalance < monto) {
if (!confirm(`Saldo insuficiente (${currentBalance.toFixed(2)}€). ¿Continuar de todos modos?`)) {
return;
}
}
}
}
// Create transaction
var ticketId = safeuuid("");
var transactionData = {
@@ -498,7 +498,7 @@ PAGES.pagos = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("pagos," + ticketId);
}, 750);
}, SAVE_WAIT);
});
}
@@ -1337,7 +1337,7 @@ PAGES.pagos = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("pagos," + transactionId);
}, 750);
}, SAVE_WAIT);
});
};

View File

@@ -1,12 +1,15 @@
PERMS["personas"] = "Personas"
PERMS["personas:edit"] = "&gt; Editar"
PERMS["personas"] = "Personas";
PERMS["personas:edit"] = "&gt; Editar";
PAGES.personas = {
navcss: "btn3",
icon: "static/appico/File_Person.svg",
AccessControl: true,
Title: "Personas",
edit: function (mid) {
if (!checkRole("personas:edit")) {setUrlHash("personas");return}
if (!checkRole("personas:edit")) {
setUrlHash("personas");
return;
}
var nameh1 = safeuuid();
var permisosdet = safeuuid();
var field_nombre = safeuuid();
@@ -21,59 +24,68 @@ PAGES.personas = {
var btn_borrar = safeuuid();
var btn_ver_monedero = safeuuid();
container.innerHTML = `
<h1>Persona <code id="${nameh1}"></code></h1>
${BuildQR("personas," + mid, "Esta Persona")}
<fieldset>
<label>
Nombre<br>
<input type="text" id="${field_nombre}"><br><br>
</label>
<label>
Zona<br>
<input type="text" id="${field_zona}"><br><br>
</label>
</label>
<details>
<summary>Permisos</summary>
<form id="${permisosdet}">
</form>
</details>
<label>
Anilla<br>
<input type="color" id="${field_anilla}"><br><br>
</label>
<label>
Foto (PNG o JPG)<br>
<img id="${render_foto}" height="100px" style="border: 3px inset; min-width: 7px;" src="static/ico/user_generic.png">
<input type="file" accept="image/*" id="${field_foto}" style="display: none;"><br><br>
</label>
<details style="background: #e3f2fd; border: 2px solid #2196f3; border-radius: 8px; padding: 10px; margin: 15px 0;">
<summary style="cursor: pointer; font-weight: bold; color: #1976d2;">💳 Tarjeta Monedero</summary>
<div style="padding: 15px;">
<label>
Balance Actual<br>
<input type="number" step="0.01" id="${field_monedero_balance}" style="font-size: 24px; font-weight: bold; color: #1976d2;"><br>
<small>Se actualiza automáticamente con las transacciones</small><br><br>
</label>
<label>
Notas del Monedero<br>
<textarea id="${field_monedero_notas}" rows="3" placeholder="Notas adicionales sobre el monedero..."></textarea><br><br>
</label>
<button type="button" id="${btn_ver_monedero}" class="btn5">Ver Transacciones del Monedero</button>
</div>
</details>
<h1>Persona <code id="${nameh1}"></code></h1>
${BuildQR("personas," + mid, "Esta Persona")}
<fieldset>
<label>
Nombre<br>
<input type="text" id="${field_nombre}"><br><br>
</label>
<label>
Zona<br>
<input type="text" id="${field_zona}"><br><br>
</label>
</label>
<details>
<summary>Permisos</summary>
<form id="${permisosdet}">
</form>
</details>
<label>
Anilla<br>
<input type="color" id="${field_anilla}"><br><br>
</label>
<label>
Foto (PNG o JPG)<br>
<img id="${render_foto}" height="100px" style="border: 3px inset; min-width: 7px;" src="static/ico/user_generic.png">
<input type="file" accept="image/*" id="${field_foto}" style="display: none;"><br><br>
</label>
<details style="background: #e3f2fd; border: 2px solid #2196f3; border-radius: 8px; padding: 10px; margin: 15px 0;">
<summary style="cursor: pointer; font-weight: bold; color: #1976d2;">💳 Tarjeta Monedero</summary>
<div style="padding: 15px;">
<label>
Balance Actual<br>
<input type="number" step="0.01" id="${field_monedero_balance}" style="font-size: 24px; font-weight: bold; color: #1976d2;"><br>
<small>Se actualiza automáticamente con las transacciones</small><br><br>
</label>
<label>
Notas del Monedero<br>
<textarea id="${field_monedero_notas}" rows="3" placeholder="Notas adicionales sobre el monedero..."></textarea><br><br>
</label>
<button type="button" id="${btn_ver_monedero}" class="btn5">Ver Transacciones del Monedero</button>
</div>
</details>
<details style="background: #e3f2fd; border: 2px solid #21f328ff; border-radius: 8px; padding: 10px; margin: 15px 0;">
<summary style="cursor: pointer; font-weight: bold; color: #38d219ff;">Generar enlaces</summary>
<div style="padding: 15px;">
<label>
Inicio de sesión automatico<br>
<input type="url" value="https://" style="font-size: 24px; font-weight: bold; color: #1976d2;"><br>
</label>
</div>
</details>
<label>
Notas<br>
<textarea id="${field_notas}"></textarea><br><br>
</label><hr>
<button class="btn5" id="${btn_guardar}">Guardar</button>
<button class="rojo" id="${btn_borrar}">Borrar</button>
</fieldset>
`;
<label>
Notas<br>
<textarea id="${field_notas}"></textarea><br><br>
</label><hr>
<button class="btn5" id="${btn_guardar}">Guardar</button>
<button class="rojo" id="${btn_borrar}">Borrar</button>
</fieldset>
`;
var resized = "";
var pdel = document.getElementById(permisosdet)
var pdel = document.getElementById(permisosdet);
gun
.get(TABLE)
.get("personas")
@@ -81,20 +93,20 @@ PAGES.personas = {
.once((data, key) => {
function load_data(data, ENC = "") {
document.getElementById(nameh1).innerText = key;
var pot = "<ul>"
var pot = "<ul>";
Object.entries(PERMS).forEach((page) => {
var c = ""
var c = "";
if ((data["Roles"] || ",").split(",").includes(page[0])) {
c = "checked"
c = "checked";
}
pot += `
<li><label>
<input name="perm" value="${page[0]}" type="checkbox" ${c}>
${page[1]}
</label></li>
`
})
pdel.innerHTML = pot + "</ul>"
`;
});
pdel.innerHTML = pot + "</ul>";
document.getElementById(field_nombre).value = data["Nombre"] || "";
document.getElementById(field_zona).value = data["Region"] || "";
document.getElementById(field_anilla).value = data["SC_Anilla"] || "";
@@ -102,8 +114,10 @@ PAGES.personas = {
data["Foto"] || "static/ico/user_generic.png";
resized = data["Foto"] || "static/ico/user_generic.png";
document.getElementById(field_notas).value = data["markdown"] || "";
document.getElementById(field_monedero_balance).value = data["Monedero_Balance"] || 0;
document.getElementById(field_monedero_notas).value = data["Monedero_Notas"] || "";
document.getElementById(field_monedero_balance).value =
data["Monedero_Balance"] || 0;
document.getElementById(field_monedero_notas).value =
data["Monedero_Notas"] || "";
}
if (typeof data == "string") {
TS_decrypt(data, SECRET, (data) => {
@@ -130,7 +144,7 @@ PAGES.personas = {
);
});
document.getElementById(btn_guardar).onclick = () => {
var dt = new FormData(pdel)
var dt = new FormData(pdel);
var data = {
Nombre: document.getElementById(field_nombre).value,
Region: document.getElementById(field_zona).value,
@@ -138,7 +152,9 @@ PAGES.personas = {
SC_Anilla: document.getElementById(field_anilla).value,
Foto: resized,
markdown: document.getElementById(field_notas).value,
Monedero_Balance: parseFloat(document.getElementById(field_monedero_balance).value) || 0,
Monedero_Balance:
parseFloat(document.getElementById(field_monedero_balance).value) ||
0,
Monedero_Notas: document.getElementById(field_monedero_notas).value,
};
var enc = TS_encrypt(data, SECRET, (encrypted) => {
@@ -148,7 +164,7 @@ PAGES.personas = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("personas");
}, 750);
}, SAVE_WAIT);
});
};
document.getElementById(btn_ver_monedero).onclick = () => {
@@ -160,22 +176,25 @@ PAGES.personas = {
toastr.error("Borrado!");
setTimeout(() => {
setUrlHash("personas");
}, 750);
}, SAVE_WAIT);
}
};
},
index: function () {
if (!checkRole("personas")) {setUrlHash("index");return}
if (!checkRole("personas")) {
setUrlHash("index");
return;
}
var btn_new = safeuuid();
container.innerHTML = `
<h1>Personas</h1>
<button id="${btn_new}">Nueva Persona</button>
<div id="tableContainer"></div>
`;
<h1>Personas</h1>
<button id="${btn_new}">Nueva Persona</button>
<div id="tableContainer"></div>
`;
const config = [
{
label: "Persona",
{
label: "Persona",
type: "persona",
self: true,
},
@@ -191,12 +210,12 @@ PAGES.personas = {
undefined,
true // Enable global search bar
);
if (!checkRole("personas:edit")) {
document.getElementById(btn_new).style.display = "none"
} else {
document.getElementById(btn_new).onclick = () => {
setUrlHash("personas," + safeuuid(""));
};
}
if (!checkRole("personas:edit")) {
document.getElementById(btn_new).style.display = "none";
} else {
document.getElementById(btn_new).onclick = () => {
setUrlHash("personas," + safeuuid(""));
};
}
},
};

View File

@@ -23,39 +23,39 @@ PAGES.supercafe = {
var btn_guardar2 = safeuuid();
var btn_borrar = safeuuid();
container.innerHTML = `
<h1>Comanda <code id="${nameh1}"></code></h1>
<button onclick="setUrlHash('supercafe');">Salir</button>
<fieldset style="text-align: center;">
<legend>Rellenar comanda</legend>
<label style="display: none;">
Fecha<br>
<input readonly disabled type="text" id="${field_fecha}" value=""><br><br>
</label>
<label style="display: none;">
Persona<br>
<input type="hidden" id="${field_persona}">
<br><br>
</label>
<label style="display: none;">
Comanda (utiliza el panel de relleno)<br>
<textarea readonly disabled id="${field_comanda}"></textarea><br><br>
</label>
<div id="${div_actions}" open>
<!--<summary>Mostrar botones de relleno</summary>-->
</div>
<label>
Notas<br>
<textarea id="${field_notas}"></textarea><br><br>
</label>
<label style="display: none;">
Estado<br>
<input readonly disabled type="text" id="${field_estado}" value="%%">
<br>Modificar en el listado de comandas<br>
</label>
<button id=${btn_guardar} class="btn5">Guardar</button>
<button id=${btn_borrar} class="rojo">Borrar</button>
</fieldset>
`;
<h1>Comanda <code id="${nameh1}"></code></h1>
<button onclick="setUrlHash('supercafe');">Salir</button>
<fieldset style="text-align: center;">
<legend>Rellenar comanda</legend>
<label style="display: none;">
Fecha<br>
<input readonly disabled type="text" id="${field_fecha}" value=""><br><br>
</label>
<label style="display: none;">
Persona<br>
<input type="hidden" id="${field_persona}">
<br><br>
</label>
<label style="display: none;">
Comanda (utiliza el panel de relleno)<br>
<textarea readonly disabled id="${field_comanda}"></textarea><br><br>
</label>
<div id="${div_actions}" open>
<!--<summary>Mostrar botones de relleno</summary>-->
</div>
<label>
Notas<br>
<textarea id="${field_notas}"></textarea><br><br>
</label>
<label style="display: none;">
Estado<br>
<input readonly disabled type="text" id="${field_estado}" value="%%">
<br>Modificar en el listado de comandas<br>
</label>
<button id=${btn_guardar} class="btn5">Guardar</button>
<button id=${btn_borrar} class="rojo">Borrar</button>
</fieldset>
`;
var currentData = {};
var currentPersonaID = "";
var divact = document.getElementById(div_actions);
@@ -126,7 +126,7 @@ PAGES.supercafe = {
setTimeout(() => {
document.getElementById("actionStatus").style.display = "none";
setUrlHash("supercafe");
}, 750);
}, SAVE_WAIT);
});
};
document.getElementById(btn_borrar).onclick = () => {
@@ -138,7 +138,7 @@ PAGES.supercafe = {
betterGunPut(gun.get(TABLE).get("supercafe").get(mid), null);
setTimeout(() => {
setUrlHash("supercafe");
}, 750);
}, SAVE_WAIT);
}
};
},
@@ -165,24 +165,24 @@ PAGES.supercafe = {
var tts_check = safeuuid();
var old = {};
container.innerHTML = `
<h1>SuperCafé - Total: <span id="${totalprecio}">0</span>c</h1>
<button id="${btn_new}" style="${sc_nobtn};">Nueva comanda</button>
<br>
<label>
<b>Habilitar avisos:</b>
<input type="checkbox" id="${tts_check}" style="height: 25px;width: 25px;">
</label>
<h1>SuperCafé - Total: <span id="${totalprecio}">0</span>c</h1>
<button id="${btn_new}" style="${sc_nobtn};">Nueva comanda</button>
<br>
<label>
<b>Habilitar avisos:</b>
<input type="checkbox" id="${tts_check}" style="height: 25px;width: 25px;">
</label>
<details style="background: beige; padding: 15px; border-radius: 15px; border: 2px solid black" open>
<summary>Todas las comandas</summary>
<div id="cont1"></div>
</details>
<br>
<details style="background: lightpink; padding: 15px; border-radius: 15px; border: 2px solid black" open>
<summary>Deudas</summary>
<div id="cont2"></div>
</details>
`;
<details style="background: beige; padding: 15px; border-radius: 15px; border: 2px solid black" open>
<summary>Todas las comandas</summary>
<div id="cont1"></div>
</details>
<br>
<details style="background: lightpink; padding: 15px; border-radius: 15px; border: 2px solid black" open>
<summary>Deudas</summary>
<div id="cont2"></div>
</details>
`;
var config = [
{
key: "Persona",

View File

@@ -1,5 +1,7 @@
var CACHE = "telesec_%%VERSIONCO%%"
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js');
var CACHE = "telesec_%%VERSIONCO%%";
importScripts(
"https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js"
);
self.addEventListener("message", (event) => {
if (event.data && event.data.type === "SKIP_WAITING") {
@@ -8,8 +10,8 @@ self.addEventListener("message", (event) => {
});
workbox.routing.registerRoute(
new RegExp('/*'),
new RegExp("/*"),
new workbox.strategies.StaleWhileRevalidate({
cacheName: CACHE
cacheName: CACHE,
})
);

View File

@@ -1,8 +0,0 @@
{
"name": "telesec",
"compatibility_date": "2025-12-12",
"assets": {
"directory": "./dist",
},
"pages_build_output_dir": "./dist"
}