From 879554a7ab626e8441a3670ff9504b20e5e33d58 Mon Sep 17 00:00:00 2001 From: Naiel <109038805+naielv@users.noreply.github.com> Date: Wed, 25 Feb 2026 13:31:05 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Implementar=20limpieza=20autom=C3=A1tic?= =?UTF-8?q?a=20de=20men=C3=BAs=20antiguos=20en=20el=20comedor=20y=20elimin?= =?UTF-8?q?ar=20la=20tienda=20de=20apps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app_logic.js | 13 +- src/app_modules.js | 620 ---------------------------------------- src/index.html | 1 - src/page/comedor.js | 154 +++++++--- src/page/tienda_apps.js | 176 ------------ 5 files changed, 110 insertions(+), 854 deletions(-) delete mode 100644 src/page/tienda_apps.js diff --git a/src/app_logic.js b/src/app_logic.js index a97d717..3d4bf59 100644 --- a/src/app_logic.js +++ b/src/app_logic.js @@ -8,7 +8,7 @@ function tableScroll(query) { //var secretTokenEl = document.getElementById("secretToken"); var container = document.getElementById('container'); -function open_page(params, retryAfterExternalLoad = false) { +function open_page(params) { // Clear stored event listeners and timers EventListeners.GunJS = []; EventListeners.Timeout.forEach((ev) => clearTimeout(ev)); @@ -32,21 +32,10 @@ function open_page(params, retryAfterExternalLoad = false) { var path = params.split(','); var app = path[0]; if (!PAGES[app]) { - if (!retryAfterExternalLoad && typeof TS_loadExternalAppsFromDB === 'function') { - TS_loadExternalAppsFromDB().then(() => { - open_page(params, true); - }); - return; - } toastr.error('La app solicitada no existe.'); setUrlHash('index'); return; } - if (typeof TS_isAppInstalled === 'function' && !TS_isAppInstalled(app)) { - toastr.error('Esta app no está instalada. Instálala desde la Tienda de apps.'); - setUrlHash('tienda_apps'); - return; - } if (path[1] == undefined) { PAGES[app].index(); return; diff --git a/src/app_modules.js b/src/app_modules.js index f841c96..179c6c5 100644 --- a/src/app_modules.js +++ b/src/app_modules.js @@ -1726,616 +1726,6 @@ var PERMS = { ADMIN: 'Administrador', }; -var TS_INSTALLED_APPS_CACHE = null; -var TS_INSTALLED_APPS_CACHE_KEY = ''; -var TS_INSTALLED_APPS_LOADING = false; -var TS_ESSENTIAL_APPS = new Set(['index', 'personas', 'dataman']); -var TS_LOCKED_APPS = new Set(['index', 'personas', 'dataman']); -var TS_APPS_SYNC_LISTENER_ID = null; -var TS_APPS_SYNC_REFRESH_PENDING = false; - -function TS_getAppInstallStorageKey() { - var dbName = 'telesec'; - try { - dbName = typeof getDBName === 'function' ? getDBName() : 'telesec'; - } catch (e) { - dbName = 'telesec'; - } - var personaId = SUB_LOGGED_IN_ID || 'anon'; - return 'TELESEC_INSTALLED_APPS::' + dbName + '::' + personaId; -} - -function TS_getAppInstallDocId() { - var dbName = 'telesec'; - try { - dbName = typeof getDBName === 'function' ? getDBName() : 'telesec'; - } catch (e) { - dbName = 'telesec'; - } - var personaId = SUB_LOGGED_IN_ID || 'anon'; - return 'installed_apps::' + dbName + '::' + personaId; -} - -function TS_buildDefaultInstalledSet() { - var installedSet = new Set(); - TS_ESSENTIAL_APPS.forEach((key) => { - if (!PAGES[key]) return; - if (TS_isSystemApp(key)) return; - if (PAGES[key].ExternalApp === true) return; - if (PAGES[key].Esconder === true) return; - installedSet.add(key); - }); - TS_LOCKED_APPS.forEach((key) => { - if (PAGES[key] && PAGES[key].Esconder !== true) { - installedSet.add(key); - } - }); - return installedSet; -} - -function TS_parseInstalledAppsPayload(payload) { - if (!payload || !Array.isArray(payload.apps)) return null; - var set = new Set(); - payload.apps.forEach((appKey) => { - if (typeof appKey === 'string' && appKey.trim() !== '') { - set.add(appKey); - } - }); - return set; -} - -function TS_readInstalledAppsFallback() { - try { - var raw = localStorage.getItem(TS_getAppInstallStorageKey()); - if (!raw) return null; - var parsed = JSON.parse(raw); - return TS_parseInstalledAppsPayload(parsed); - } catch (e) { - return null; - } -} - -function TS_writeInstalledAppsFallback(appSet) { - var apps = []; - if (appSet && typeof appSet.forEach === 'function') { - appSet.forEach((appKey) => { - if (typeof appKey === 'string' && appKey.trim() !== '') { - apps.push(appKey); - } - }); - } - localStorage.setItem( - TS_getAppInstallStorageKey(), - JSON.stringify({ version: 1, apps: apps.sort(), updatedAt: CurrentISOTime() }) - ); -} - -function TS_setInstalledAppsCache(appSet) { - TS_LOCKED_APPS.forEach((key) => { - if (PAGES[key] && PAGES[key].Esconder !== true) { - appSet.add(key); - } - }); - TS_INSTALLED_APPS_CACHE = appSet; - TS_INSTALLED_APPS_CACHE_KEY = TS_getAppInstallDocId(); - TS_writeInstalledAppsFallback(appSet); -} - -function TS_persistInstalledAppsToDB(appSet) { - if (!window.DB || typeof DB.put !== 'function') { - return Promise.resolve(false); - } - var apps = []; - appSet.forEach((appKey) => { - if (typeof appKey === 'string' && appKey.trim() !== '') { - apps.push(appKey); - } - }); - return DB.put('config', TS_getAppInstallDocId(), { - version: 1, - apps: apps.sort(), - updatedAt: CurrentISOTime(), - }) - .then(() => true) - .catch((e) => { - console.warn('Error saving installed apps in DB', e); - return false; - }); -} - -function TS_loadInstalledAppsFromDB(forceReload = false) { - var expectedKey = TS_getAppInstallDocId(); - if (!forceReload && TS_INSTALLED_APPS_CACHE && TS_INSTALLED_APPS_CACHE_KEY === expectedKey) { - return Promise.resolve(TS_INSTALLED_APPS_CACHE); - } - if (TS_INSTALLED_APPS_LOADING) { - return Promise.resolve(TS_INSTALLED_APPS_CACHE); - } - TS_INSTALLED_APPS_LOADING = true; - - var fallbackSet = TS_readInstalledAppsFallback() || TS_buildDefaultInstalledSet(); - TS_setInstalledAppsCache(fallbackSet); - - if (!window.DB || typeof DB.get !== 'function') { - TS_INSTALLED_APPS_LOADING = false; - return Promise.resolve(TS_INSTALLED_APPS_CACHE); - } - - return DB.get('config', expectedKey) - .then((raw) => { - if (raw == null) { - TS_INSTALLED_APPS_LOADING = false; - return TS_persistInstalledAppsToDB(TS_INSTALLED_APPS_CACHE).then(() => TS_INSTALLED_APPS_CACHE); - } - - return new Promise((resolve) => { - if (typeof raw === 'string') { - TS_decrypt( - raw, - SECRET, - (decrypted) => { - var parsed = TS_parseInstalledAppsPayload(decrypted); - if (parsed) { - TS_setInstalledAppsCache(parsed); - } - TS_INSTALLED_APPS_LOADING = false; - resolve(TS_INSTALLED_APPS_CACHE); - }, - 'config', - expectedKey - ); - } else { - var parsed = TS_parseInstalledAppsPayload(raw); - if (parsed) { - TS_setInstalledAppsCache(parsed); - } - TS_INSTALLED_APPS_LOADING = false; - resolve(TS_INSTALLED_APPS_CACHE); - } - }); - }) - .catch((e) => { - console.warn('Error loading installed apps from DB', e); - TS_INSTALLED_APPS_LOADING = false; - return TS_INSTALLED_APPS_CACHE; - }); -} - -function TS_getInstalledAppsSet() { - var expectedKey = TS_getAppInstallDocId(); - if (!TS_INSTALLED_APPS_CACHE || TS_INSTALLED_APPS_CACHE_KEY !== expectedKey) { - TS_loadInstalledAppsFromDB().then(() => { - SetPages(); - }); - return null; - } - return TS_INSTALLED_APPS_CACHE; -} - -function TS_setInstalledAppsSet(appSet) { - TS_setInstalledAppsCache(appSet); - TS_persistInstalledAppsToDB(appSet); -} - -function TS_isSystemApp(appKey) { - if (appKey === 'login') return true; - if (!PAGES[appKey]) return false; - return PAGES[appKey].SystemApp === true; -} - -function TS_isLockedApp(appKey) { - return TS_LOCKED_APPS.has(appKey); -} - -function TS_isMandatoryApp(appKey) { - return TS_isSystemApp(appKey) || TS_isLockedApp(appKey); -} - -function TS_isAppInstalled(appKey) { - if (TS_isMandatoryApp(appKey)) return true; - var installedSet = TS_getInstalledAppsSet(); - if (installedSet == null) { - return true; - } - return installedSet.has(appKey); -} - -function TS_installApp(appKey) { - if (!PAGES[appKey] || TS_isSystemApp(appKey)) return; - var installedSet = TS_getInstalledAppsSet(); - if (installedSet == null) { - installedSet = TS_buildDefaultInstalledSet(); - } - installedSet.add(appKey); - if (appKey === 'supercafe' && PAGES.pagos) { - installedSet.add('pagos'); - } - TS_setInstalledAppsSet(installedSet); -} - -function TS_uninstallApp(appKey) { - if (!PAGES[appKey] || TS_isMandatoryApp(appKey)) return; - var installedSet = TS_getInstalledAppsSet(); - if (installedSet == null) { - installedSet = TS_buildDefaultInstalledSet(); - } - installedSet.delete(appKey); - TS_setInstalledAppsSet(installedSet); -} - -function TS_resetInstalledApps() { - var defaults = TS_buildDefaultInstalledSet(); - TS_setInstalledAppsSet(defaults); -} - -function TS_getAppCatalog() { - return Object.keys(PAGES) - .filter((key) => PAGES[key].Esconder !== true) - .map((key) => { - return { - key: key, - title: PAGES[key].Title || key, - icon: PAGES[key].icon || 'static/appico/application_enterprise.png', - installed: TS_isAppInstalled(key), - system: TS_isSystemApp(key), - canAccess: !PAGES[key].AccessControl || checkRole(key), - requiresRole: PAGES[key].AccessControl === true, - }; - }) - .sort((a, b) => a.title.localeCompare(b.title, 'es')); -} - -var TS_EXTERNAL_APPS_CACHE = []; -var TS_EXTERNAL_APPS_CACHE_KEY = ''; -var TS_EXTERNAL_APPS_LOADING = false; -var TS_EXTERNAL_APPS_READY = false; - -function TS_getExternalAppsStorageKey() { - var dbName = 'telesec'; - try { - dbName = typeof getDBName === 'function' ? getDBName() : 'telesec'; - } catch (e) { - dbName = 'telesec'; - } - var personaId = SUB_LOGGED_IN_ID || 'anon'; - return 'TELESEC_EXTERNAL_APPS::' + dbName + '::' + personaId; -} - -function TS_getExternalAppsDocId() { - var dbName = 'telesec'; - try { - dbName = typeof getDBName === 'function' ? getDBName() : 'telesec'; - } catch (e) { - dbName = 'telesec'; - } - var personaId = SUB_LOGGED_IN_ID || 'anon'; - return 'external_apps::' + dbName + '::' + personaId; -} - -function TS_parseExternalAppsPayload(payload) { - if (!payload || !Array.isArray(payload.apps)) return []; - return payload.apps.filter((entry) => { - return ( - entry && - typeof entry.appKey === 'string' && - entry.appKey.trim() !== '' && - typeof entry.code === 'string' && - entry.code.trim() !== '' - ); - }); -} - -function TS_readExternalAppsFallback() { - try { - var raw = localStorage.getItem(TS_getExternalAppsStorageKey()); - if (!raw) return []; - return TS_parseExternalAppsPayload(JSON.parse(raw)); - } catch (e) { - return []; - } -} - -function TS_writeExternalAppsFallback(appsList) { - localStorage.setItem( - TS_getExternalAppsStorageKey(), - JSON.stringify({ - version: 1, - apps: appsList, - updatedAt: CurrentISOTime(), - }) - ); -} - -function TS_setExternalAppsCache(appsList) { - TS_EXTERNAL_APPS_CACHE = Array.isArray(appsList) ? appsList : []; - TS_EXTERNAL_APPS_CACHE_KEY = TS_getExternalAppsDocId(); - TS_EXTERNAL_APPS_READY = true; - TS_writeExternalAppsFallback(TS_EXTERNAL_APPS_CACHE); -} - -function TS_saveExternalAppsToDB(appsList) { - if (!window.DB || typeof DB.put !== 'function') { - return Promise.resolve(false); - } - return DB.put('config', TS_getExternalAppsDocId(), { - version: 1, - apps: appsList, - updatedAt: CurrentISOTime(), - }) - .then(() => true) - .catch((e) => { - console.warn('Error saving external apps in DB', e); - return false; - }); -} - -function TS_evalExternalAppCode(code, expectedAppKey = '') { - if (typeof code !== 'string' || code.trim() === '') { - throw new Error('Código vacío en app externa.'); - } - - var beforeKeys = Object.keys(PAGES); - var beforeSet = new Set(beforeKeys); - try { - new Function(code)(); - } catch (e) { - throw new Error('Error ejecutando app externa: ' + (e && e.message ? e.message : e)); - } - - var afterKeys = Object.keys(PAGES); - var newKeys = afterKeys.filter((key) => !beforeSet.has(key)); - var appKey = expectedAppKey || ''; - - if (!appKey) { - if (newKeys.length === 0) { - throw new Error('La app externa no registró ninguna entrada en PAGES.'); - } - appKey = newKeys[0]; - } - - if (!PAGES[appKey]) { - throw new Error('No se pudo detectar la app externa cargada.'); - } - - if (beforeSet.has(appKey) && PAGES[appKey].ExternalApp !== true) { - throw new Error('La app externa intenta sobrescribir una app interna: ' + appKey); - } - - PAGES[appKey].ExternalApp = true; - PAGES[appKey].SystemApp = false; - - return { - appKey: appKey, - title: PAGES[appKey].Title || appKey, - icon: PAGES[appKey].icon || 'static/appico/application_enterprise.png', - }; -} - -function TS_applyExternalAppsRegistry(appsList) { - appsList.forEach((entry) => { - try { - if (entry.appKey && PAGES[entry.appKey] && PAGES[entry.appKey].ExternalApp === true) { - return; - } - TS_evalExternalAppCode(entry.code, entry.appKey || ''); - } catch (e) { - console.warn('Error loading external app', entry && entry.appKey, e); - } - }); -} - -function TS_loadExternalAppsFromDB(forceReload = false) { - var expectedKey = TS_getExternalAppsDocId(); - if (!forceReload && TS_EXTERNAL_APPS_READY && TS_EXTERNAL_APPS_CACHE_KEY === expectedKey) { - return Promise.resolve(TS_EXTERNAL_APPS_CACHE); - } - if (TS_EXTERNAL_APPS_LOADING) { - return Promise.resolve(TS_EXTERNAL_APPS_CACHE); - } - TS_EXTERNAL_APPS_LOADING = true; - - var fallback = TS_readExternalAppsFallback(); - TS_setExternalAppsCache(fallback); - TS_applyExternalAppsRegistry(TS_EXTERNAL_APPS_CACHE); - - if (!window.DB || typeof DB.get !== 'function') { - TS_EXTERNAL_APPS_LOADING = false; - return Promise.resolve(TS_EXTERNAL_APPS_CACHE); - } - - return DB.get('config', expectedKey) - .then((raw) => { - if (raw == null) { - TS_EXTERNAL_APPS_LOADING = false; - return TS_saveExternalAppsToDB(TS_EXTERNAL_APPS_CACHE).then(() => TS_EXTERNAL_APPS_CACHE); - } - - return new Promise((resolve) => { - if (typeof raw === 'string') { - TS_decrypt( - raw, - SECRET, - (decrypted) => { - var parsed = TS_parseExternalAppsPayload(decrypted); - TS_setExternalAppsCache(parsed); - TS_applyExternalAppsRegistry(TS_EXTERNAL_APPS_CACHE); - TS_EXTERNAL_APPS_LOADING = false; - resolve(TS_EXTERNAL_APPS_CACHE); - }, - 'config', - expectedKey - ); - } else { - var parsed = TS_parseExternalAppsPayload(raw); - TS_setExternalAppsCache(parsed); - TS_applyExternalAppsRegistry(TS_EXTERNAL_APPS_CACHE); - TS_EXTERNAL_APPS_LOADING = false; - resolve(TS_EXTERNAL_APPS_CACHE); - } - }); - }) - .catch((e) => { - console.warn('Error loading external apps from DB', e); - TS_EXTERNAL_APPS_LOADING = false; - return TS_EXTERNAL_APPS_CACHE; - }); -} - -function TS_getExternalAppsCatalog() { - var expectedKey = TS_getExternalAppsDocId(); - if (!TS_EXTERNAL_APPS_READY || TS_EXTERNAL_APPS_CACHE_KEY !== expectedKey) { - TS_loadExternalAppsFromDB().then(() => { - SetPages(); - }); - return []; - } - return TS_EXTERNAL_APPS_CACHE.map((entry) => { - return { - appKey: entry.appKey, - title: entry.title || entry.appKey, - sourceType: entry.sourceType || 'file', - source: entry.source || '', - installedAt: entry.installedAt || '', - installed: TS_isAppInstalled(entry.appKey), - }; - }); -} - -function TS_installExternalAppFromCode(code, sourceType = 'file', sourceRef = '') { - return TS_loadExternalAppsFromDB().then(() => { - var info = TS_evalExternalAppCode(code, ''); - var next = TS_EXTERNAL_APPS_CACHE.filter((entry) => entry.appKey !== info.appKey); - var item = { - id: safeuuid('extapp-'), - appKey: info.appKey, - title: info.title, - icon: info.icon, - sourceType: sourceType, - source: sourceRef, - code: code, - installedAt: CurrentISOTime(), - updatedAt: CurrentISOTime(), - }; - next.push(item); - TS_setExternalAppsCache(next); - TS_saveExternalAppsToDB(next); - TS_installApp(info.appKey); - return item; - }); -} - -function TS_uninstallExternalApp(appKey) { - return TS_loadExternalAppsFromDB().then(() => { - var next = TS_EXTERNAL_APPS_CACHE.filter((entry) => entry.appKey !== appKey); - TS_setExternalAppsCache(next); - TS_saveExternalAppsToDB(next); - TS_uninstallApp(appKey); - if (PAGES[appKey] && PAGES[appKey].ExternalApp === true) { - delete PAGES[appKey]; - } - return true; - }); -} - -function TS_resetAppsToDefault() { - return TS_loadExternalAppsFromDB().then(() => { - TS_EXTERNAL_APPS_CACHE.forEach((entry) => { - var appKey = entry.appKey; - if (PAGES[appKey] && PAGES[appKey].ExternalApp === true) { - delete PAGES[appKey]; - } - }); - TS_setExternalAppsCache([]); - TS_saveExternalAppsToDB([]); - TS_resetInstalledApps(); - return true; - }); -} - -function TS_queueAppsUIRefresh() { - if (TS_APPS_SYNC_REFRESH_PENDING) return; - TS_APPS_SYNC_REFRESH_PENDING = true; - setTimeout(() => { - TS_APPS_SYNC_REFRESH_PENDING = false; - try { - SetPages(); - var currentPage = location.hash.replace('#', '').split('?')[0].split(',')[0]; - if (currentPage === 'tienda_apps' && PAGES.tienda_apps && typeof PAGES.tienda_apps.index === 'function') { - PAGES.tienda_apps.index(); - } - } catch (e) { - console.warn('Apps UI refresh warning', e); - } - }, 50); -} - -function TS_applyInstalledAppsFromConfigValue(raw, key) { - if (key !== TS_getAppInstallDocId()) return; - if (raw == null) { - TS_setInstalledAppsCache(TS_buildDefaultInstalledSet()); - TS_queueAppsUIRefresh(); - return; - } - if (typeof raw === 'string') { - TS_decrypt( - raw, - SECRET, - (decrypted) => { - var parsed = TS_parseInstalledAppsPayload(decrypted); - if (parsed) { - TS_setInstalledAppsCache(parsed); - TS_queueAppsUIRefresh(); - } - }, - 'config', - key - ); - return; - } - var parsed = TS_parseInstalledAppsPayload(raw); - if (parsed) { - TS_setInstalledAppsCache(parsed); - TS_queueAppsUIRefresh(); - } -} - -function TS_applyExternalAppsFromConfigValue(raw, key) { - if (key !== TS_getExternalAppsDocId()) return; - if (raw == null) { - TS_setExternalAppsCache([]); - TS_queueAppsUIRefresh(); - return; - } - if (typeof raw === 'string') { - TS_decrypt( - raw, - SECRET, - (decrypted) => { - var parsed = TS_parseExternalAppsPayload(decrypted); - TS_setExternalAppsCache(parsed); - TS_applyExternalAppsRegistry(TS_EXTERNAL_APPS_CACHE); - TS_queueAppsUIRefresh(); - }, - 'config', - key - ); - return; - } - var parsed = TS_parseExternalAppsPayload(raw); - TS_setExternalAppsCache(parsed); - TS_applyExternalAppsRegistry(TS_EXTERNAL_APPS_CACHE); - TS_queueAppsUIRefresh(); -} - -function TS_initAppsRealtimeSync() { - if (!window.DB || typeof DB.map !== 'function') return; - if (TS_APPS_SYNC_LISTENER_ID) return; - TS_APPS_SYNC_LISTENER_ID = DB.map('config', (data, key) => { - TS_applyInstalledAppsFromConfigValue(data, key); - TS_applyExternalAppsFromConfigValue(data, key); - }); -} - function checkRole(role) { var roles = SUB_LOGGED_IN_DETAILS.Roles || ''; var rolesArr = roles.split(','); @@ -2346,21 +1736,11 @@ function checkRole(role) { } } function SetPages() { - TS_initAppsRealtimeSync(); - var expectedExternalKey = TS_getExternalAppsDocId(); - if (!TS_EXTERNAL_APPS_READY || TS_EXTERNAL_APPS_CACHE_KEY !== expectedExternalKey) { - TS_loadExternalAppsFromDB().then(() => { - SetPages(); - }); - } document.getElementById('appendApps2').innerHTML = ''; Object.keys(PAGES).forEach((key) => { if (PAGES[key].Esconder == true) { return; } - if (!TS_isAppInstalled(key)) { - return; - } if (PAGES[key].AccessControl == true) { var roles = SUB_LOGGED_IN_DETAILS.Roles || ''; var rolesArr = roles.split(','); diff --git a/src/index.html b/src/index.html index 1d0f6c9..1000b0c 100644 --- a/src/index.html +++ b/src/index.html @@ -95,7 +95,6 @@ - \ No newline at end of file diff --git a/src/page/comedor.js b/src/page/comedor.js index a23e145..00cf390 100644 --- a/src/page/comedor.js +++ b/src/page/comedor.js @@ -5,6 +5,66 @@ PAGES.comedor = { icon: 'static/appico/apple.png', AccessControl: true, Title: 'Comedor', + __cleanupOldMenus: async function () { + try { + var rows = await DB.list('comedor'); + var now = new Date(); + var todayUTC = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()); + var removed = 0; + + function parseISODateToUTC(value) { + if (!value || typeof value !== 'string') return null; + var match = value.match(/^(\d{4})-(\d{2})-(\d{2})$/); + if (!match) return null; + var y = parseInt(match[1], 10); + var m = parseInt(match[2], 10) - 1; + var d = parseInt(match[3], 10); + return Date.UTC(y, m, d); + } + + async function getFechaFromRow(row) { + var data = row.data; + if (typeof data === 'string') { + return await new Promise((resolve) => { + TS_decrypt( + data, + SECRET, + (decrypted) => { + if (decrypted && typeof decrypted === 'object') { + resolve(decrypted.Fecha || row.id.split(',')[0] || ''); + } else { + resolve(row.id.split(',')[0] || ''); + } + }, + 'comedor', + row.id + ); + }); + } + if (data && typeof data === 'object') { + return data.Fecha || row.id.split(',')[0] || ''; + } + return row.id.split(',')[0] || ''; + } + + for (const row of rows) { + var fecha = await getFechaFromRow(row); + var rowUTC = parseISODateToUTC(fecha); + if (rowUTC == null) continue; + var ageDays = Math.floor((todayUTC - rowUTC) / 86400000); + if (ageDays >= 30) { + await DB.del('comedor', row.id); + removed += 1; + } + } + + if (removed > 0) { + toastr.info('Limpieza automática: ' + removed + ' menús antiguos eliminados.'); + } + } catch (e) { + console.warn('Comedor cleanup error', e); + } + }, edit: function (mid) { if (!checkRole('comedor:edit')) { setUrlHash('comedor'); @@ -161,52 +221,56 @@ PAGES.comedor = {
`; - TS_IndexElement( - 'comedor', - [ - { - key: 'Fecha', - type: 'raw', - default: '', - label: 'Fecha', - }, - { - key: 'Tipo', - type: 'raw', - default: '', - label: 'Tipo', - }, - { - key: 'Primero_Picto', - type: 'picto', - default: '', - label: 'Primero', - labelkey: 'Primero', - }, - { - key: 'Segundo_Picto', - type: 'picto', - default: '', - label: 'Segundo', - labelkey: 'Segundo', - }, - { - key: 'Postre_Picto', - type: 'picto', - default: '', - label: 'Postre', - labelkey: 'Postre', - }, - ], - 'comedor', - document.getElementById(cont), - (data, new_tr) => { - // new_tr.style.backgroundColor = "#FFCCCB"; - if (data.Fecha == CurrentISODate()) { - new_tr.style.backgroundColor = 'lightgreen'; + var renderList = () => { + TS_IndexElement( + 'comedor', + [ + { + key: 'Fecha', + type: 'raw', + default: '', + label: 'Fecha', + }, + { + key: 'Tipo', + type: 'raw', + default: '', + label: 'Tipo', + }, + { + key: 'Primero_Picto', + type: 'picto', + default: '', + label: 'Primero', + labelkey: 'Primero', + }, + { + key: 'Segundo_Picto', + type: 'picto', + default: '', + label: 'Segundo', + labelkey: 'Segundo', + }, + { + key: 'Postre_Picto', + type: 'picto', + default: '', + label: 'Postre', + labelkey: 'Postre', + }, + ], + 'comedor', + document.getElementById(cont), + (data, new_tr) => { + // new_tr.style.backgroundColor = "#FFCCCB"; + if (data.Fecha == CurrentISODate()) { + new_tr.style.backgroundColor = 'lightgreen'; + } } - } - ); + ); + }; + + PAGES.comedor.__cleanupOldMenus().finally(renderList); if (!checkRole('comedor:edit')) { document.getElementById(btn_new).style.display = 'none'; diff --git a/src/page/tienda_apps.js b/src/page/tienda_apps.js deleted file mode 100644 index 45a1d31..0000000 --- a/src/page/tienda_apps.js +++ /dev/null @@ -1,176 +0,0 @@ -PAGES.tienda_apps = { - Title: 'Tienda de apps', - icon: 'static/appico/application_enterprise.png', - SystemApp: true, - AccessControl: true, - AccessControlRole: "admin", - index: function () { - if (!checkRole('admin')) { - setUrlHash('index'); - toastr.error('No tienes permiso para acceder a la tienda de apps.'); - return; - } - var appsContainerId = safeuuid(); - var externalContainerId = safeuuid(); - var fieldFileId = safeuuid(); - var btnFileInstallId = safeuuid(); - var btnResetId = safeuuid(); - - container.innerHTML = html` -

Tienda de apps

-

Instala o desinstala módulos personalizados para tu cuenta actual.

- - -

Apps oficiales

-
-

Apps externas instaladas

-
-
- Instalar app externa - - -
- ⚠️ Solo instala apps de fuentes de confianza. -
- `; - - var render = () => { - var catalog = TS_getAppCatalog().filter((app) => app.key !== 'index' && app.key !== 'tienda_apps'); - if (catalog.length === 0) { - document.getElementById(appsContainerId).innerHTML = 'No hay apps disponibles en el catálogo.'; - return; - } - - var htmlCards = catalog - .map((app) => { - var roleInfo = app.requiresRole - ? app.canAccess - ? 'Permiso: OK' - : 'Sin permiso de acceso' - : 'Permiso: no requerido'; - - var actionBtn = app.installed - ? TS_isMandatoryApp(app.key) - ? `` - : `` - : ``; - - return ` -
- ${app.title} -
- ${app.title} - ${app.title} - ${app.installed ? '✅ Instalada' : '⬜ No instalada'} -
-
- ${actionBtn} - ${roleInfo} -
-
- `; - }) - .join(''); - - var target = document.getElementById(appsContainerId); - target.innerHTML = htmlCards; - - target.querySelectorAll('button[data-action]').forEach((button) => { - button.onclick = () => { - var appKey = button.getAttribute('data-app'); - var action = button.getAttribute('data-action'); - if (action === 'install') { - TS_installApp(appKey); - toastr.success('App instalada: ' + appKey); - } else { - TS_uninstallApp(appKey); - toastr.info('App desinstalada: ' + appKey); - } - SetPages(); - render(); - }; - }); - - var external = TS_getExternalAppsCatalog(); - var externalTarget = document.getElementById(externalContainerId); - if (!external.length) { - externalTarget.innerHTML = 'No hay apps externas instaladas.'; - } else { - externalTarget.innerHTML = external - .map((entry) => { - return ` -
- ${entry.title} -
Clave: ${entry.appKey}
-
Origen: ${entry.sourceType} ${entry.source ? '- ' + entry.source : ''}
-
- -
-
- `; - }) - .join(''); - - externalTarget.querySelectorAll('button[data-external-action]').forEach((button) => { - button.onclick = async () => { - var appKey = button.getAttribute('data-external-app'); - await TS_uninstallExternalApp(appKey); - toastr.info('App externa desinstalada: ' + appKey); - SetPages(); - render(); - }; - }); - } - }; - - document.getElementById(btnResetId).onclick = async () => { - await TS_resetAppsToDefault(); - SetPages(); - render(); - toastr.success('Apps reestablecidas al estado por defecto.'); - }; - - document.getElementById(btnFileInstallId).onclick = async () => { - var input = document.getElementById(fieldFileId); - if (!input.files || !input.files[0]) { - toastr.error('Selecciona un archivo .telejs'); - return; - } - var file = input.files[0]; - try { - var code = await new Promise((resolve, reject) => { - var reader = new FileReader(); - reader.onload = (ev) => resolve(ev.target.result || ''); - reader.onerror = (err) => reject(err); - reader.readAsText(file); - }); - var entry = await TS_installExternalAppFromCode(code, 'file', file.name || 'archivo.telejs'); - toastr.success('App externa instalada: ' + entry.appKey); - SetPages(); - render(); - } catch (e) { - toastr.error('Error instalando archivo: ' + (e && e.message ? e.message : e)); - } - }; - - TS_loadInstalledAppsFromDB().then(() => { - TS_loadExternalAppsFromDB().then(() => { - render(); - }); - }); - }, - edit: function () { - this.index(); - }, -};