feat: Agregar modal de confirmación para eliminar apps en panel web
Frontend (index.html): - Modal elegante con backdrop blur y animación - Muestra nombre de la app a eliminar - Lista detallada de lo que se eliminará: * Servicio systemd (siax-app-*.service) * Archivo .service en /etc/systemd/system/ * Registro en monitored_apps.json * Historial de monitoreo - Botón de eliminar solo visible si app está Stopped/Failed - Diseño rojo con iconos Material Symbols - Dos botones: Cancelar (gris) y Eliminar (rojo) - Función openDeleteModal(appName) - Función closeDeleteModal() - Función confirmDelete() que llama a DELETE /api/apps/:name Backend (ya existente, no modificado): - DELETE /api/apps/:name elimina completamente: 1. systemctl stop 2. systemctl disable 3. rm archivo .service 4. systemctl daemon-reload 5. Elimina de AppManager (memoria) 6. Elimina de monitored_apps.json Flujo de eliminación: 1. Usuario detiene app 2. Aparece botón 🗑️ Eliminar 3. Click → Modal de confirmación 4. Confirm → DELETE request 5. Backend elimina todo 6. Frontend recarga tabla 7. App desaparece completamente del sistema Consecuencias de eliminación completa: ✅ No queda rastro en systemd ✅ No re-aparece en discovery ✅ No se envía a Cloud Central ✅ Limpieza total del sistema
This commit is contained in:
@@ -2242,3 +2242,89 @@
|
|||||||
[2026-01-19 08:10:32] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
[2026-01-19 08:10:32] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
[2026-01-19 08:10:32] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
[2026-01-19 08:10:32] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
[2026-01-19 08:10:32] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
[2026-01-19 08:10:32] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:11:32] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:11:32] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:11:32] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:11:32] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Sistema] Iniciando SIAX Agent
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Sistema] Escaneando servicios systemd existentes...
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Discovery] 🔍 Escaneando servicios systemd en: /etc/systemd/system
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Discovery] ✅ Directorio /etc/systemd/system accesible
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Discovery] 📊 Escaneados 131 archivos, 0 con prefijo 'siax-app-', 0 parseados exitosamente
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Config] Usando archivo de configuración: config/monitored_apps.json
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Config] ✅ Configuración cargada: 2 apps desde config/monitored_apps.json
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Sistema] Servidor detectado: siax-intel
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Sistema] Iniciando servidor unificado en puerto 8080
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Sistema] Sistema SIAX completamente operativo en puerto 8080
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Monitor] Vigilando procesos para siax-intel [SIAX-Agent/0.1.0 (linux/x86_64; Rust-Monitor)]
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Monitor] Buscando app app_tareas en API central...
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Monitor] App app_tareas encontrada en cloud (ID: 3)
|
||||||
|
[2026-01-19 08:11:38] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Monitor] Buscando app fidelizacion en API central...
|
||||||
|
[2026-01-19 08:11:38] [INFO] [Monitor] App fidelizacion encontrada en cloud (ID: 4)
|
||||||
|
[2026-01-19 08:11:39] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:11:45] [INFO] [WebSocket] Nueva conexión para logs de: app_tareas
|
||||||
|
[2026-01-19 08:11:48] [INFO] [WebSocket] Nueva conexión para logs de: fidelizacion
|
||||||
|
[2026-01-19 08:11:48] [INFO] [WebSocket] Conexión cerrada para: app_tareas
|
||||||
|
[2026-01-19 08:11:53] [INFO] [WebSocket] Nueva conexión para logs de: app_tareas
|
||||||
|
[2026-01-19 08:11:53] [INFO] [WebSocket] Conexión cerrada para: fidelizacion
|
||||||
|
[2026-01-19 08:11:54] [INFO] [WebSocket] Nueva conexión para logs de: fidelizacion
|
||||||
|
[2026-01-19 08:11:54] [INFO] [WebSocket] Conexión cerrada para: app_tareas
|
||||||
|
[2026-01-19 08:11:57] [INFO] [WebSocket] Nueva conexión para logs de: app_tareas
|
||||||
|
[2026-01-19 08:11:57] [INFO] [WebSocket] Conexión cerrada para: fidelizacion
|
||||||
|
[2026-01-19 08:11:59] [INFO] [WebSocket] Nueva conexión para logs de: fidelizacion
|
||||||
|
[2026-01-19 08:11:59] [INFO] [WebSocket] Conexión cerrada para: app_tareas
|
||||||
|
[2026-01-19 08:12:07] [INFO] [WebSocket] Conexión cerrada para: fidelizacion
|
||||||
|
[2026-01-19 08:12:39] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:12:39] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:12:39] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:12:39] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Sistema] Iniciando SIAX Agent
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Sistema] Escaneando servicios systemd existentes...
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Discovery] 🔍 Escaneando servicios systemd en: /etc/systemd/system
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Discovery] ✅ Directorio /etc/systemd/system accesible
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Discovery] 📊 Escaneados 131 archivos, 0 con prefijo 'siax-app-', 0 parseados exitosamente
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Config] Usando archivo de configuración: config/monitored_apps.json
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Config] ✅ Configuración cargada: 2 apps desde config/monitored_apps.json
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Sistema] Servidor detectado: siax-intel
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Sistema] Iniciando servidor unificado en puerto 8080
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Sistema] Sistema SIAX completamente operativo en puerto 8080
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Monitor] Vigilando procesos para siax-intel [SIAX-Agent/0.1.0 (linux/x86_64; Rust-Monitor)]
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Monitor] Buscando app app_tareas en API central...
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Monitor] App app_tareas encontrada en cloud (ID: 3)
|
||||||
|
[2026-01-19 08:19:19] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Monitor] Buscando app fidelizacion en API central...
|
||||||
|
[2026-01-19 08:19:19] [INFO] [Monitor] App fidelizacion encontrada en cloud (ID: 4)
|
||||||
|
[2026-01-19 08:19:19] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:20:19] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:20:19] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:20:19] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:20:19] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:21:19] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:21:19] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:21:19] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:21:20] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:22:20] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:22:20] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:22:20] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:22:20] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:23:20] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:23:20] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:23:20] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:23:20] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:24:20] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:24:20] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:24:20] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:24:20] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:25:20] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:25:20] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:25:20] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:25:20] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:26:20] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:26:20] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:26:21] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:26:21] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:27:21] [INFO] [Monitor] App app_tareas ya existe (ID: 3), actualizando...
|
||||||
|
[2026-01-19 08:27:21] [ERROR] [Monitor] Error sincronizando app_tareas | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
[2026-01-19 08:27:21] [INFO] [Monitor] App fidelizacion ya existe (ID: 4), actualizando...
|
||||||
|
[2026-01-19 08:27:21] [ERROR] [Monitor] Error sincronizando fidelizacion | HTTP 500 Internal Server Error: {"success":false,"message":"Error al actualizar el estado","error":"Table 'webControl.app_service_history' doesn't exist"}
|
||||||
|
|||||||
166
web/index.html
166
web/index.html
@@ -471,6 +471,117 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal de Confirmación para Eliminar -->
|
||||||
|
<div
|
||||||
|
id="delete-modal"
|
||||||
|
class="hidden fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="bg-white dark:bg-slate-800 rounded-2xl shadow-2xl max-w-md w-full border border-slate-200 dark:border-slate-700 animate-in fade-in zoom-in duration-200"
|
||||||
|
>
|
||||||
|
<!-- Header -->
|
||||||
|
<div
|
||||||
|
class="flex items-center gap-3 p-6 border-b border-slate-200 dark:border-slate-700"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="size-12 rounded-full bg-red-500/10 flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="material-symbols-outlined text-red-500 text-2xl"
|
||||||
|
>delete_forever</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3
|
||||||
|
class="text-lg font-bold text-slate-900 dark:text-white"
|
||||||
|
>
|
||||||
|
Eliminar Aplicación
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm text-slate-500">
|
||||||
|
Esta acción no se puede deshacer
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<div class="p-6 space-y-4">
|
||||||
|
<div
|
||||||
|
class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="text-sm text-slate-700 dark:text-slate-300 mb-3"
|
||||||
|
>
|
||||||
|
¿Estás seguro de eliminar
|
||||||
|
<strong
|
||||||
|
id="delete-app-name"
|
||||||
|
class="text-red-600 dark:text-red-400"
|
||||||
|
></strong
|
||||||
|
>?
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="text-xs text-slate-600 dark:text-slate-400 font-medium mb-2"
|
||||||
|
>
|
||||||
|
Esta acción eliminará:
|
||||||
|
</p>
|
||||||
|
<ul
|
||||||
|
class="text-xs text-slate-600 dark:text-slate-400 space-y-1.5"
|
||||||
|
>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span
|
||||||
|
class="material-symbols-outlined text-[14px] text-red-500"
|
||||||
|
>close</span
|
||||||
|
>
|
||||||
|
Servicio systemd (siax-app-*.service)
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span
|
||||||
|
class="material-symbols-outlined text-[14px] text-red-500"
|
||||||
|
>close</span
|
||||||
|
>
|
||||||
|
Archivo de configuración en /etc/systemd/system/
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span
|
||||||
|
class="material-symbols-outlined text-[14px] text-red-500"
|
||||||
|
>close</span
|
||||||
|
>
|
||||||
|
Registro en monitored_apps.json
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span
|
||||||
|
class="material-symbols-outlined text-[14px] text-red-500"
|
||||||
|
>close</span
|
||||||
|
>
|
||||||
|
Historial de monitoreo
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Actions -->
|
||||||
|
<div
|
||||||
|
class="flex gap-3 p-6 border-t border-slate-200 dark:border-slate-700"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onclick="closeDeleteModal()"
|
||||||
|
class="flex-1 px-4 py-2.5 rounded-lg border border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-300 font-medium hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors"
|
||||||
|
>
|
||||||
|
Cancelar
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onclick="confirmDelete()"
|
||||||
|
class="flex-1 px-4 py-2.5 rounded-lg bg-red-500 hover:bg-red-600 text-white font-medium transition-colors flex items-center justify-center gap-2"
|
||||||
|
>
|
||||||
|
<span class="material-symbols-outlined text-[18px]"
|
||||||
|
>delete</span
|
||||||
|
>
|
||||||
|
Eliminar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function loadApps() {
|
async function loadApps() {
|
||||||
try {
|
try {
|
||||||
@@ -585,6 +696,17 @@
|
|||||||
title="Ver logs">
|
title="Ver logs">
|
||||||
<span class="material-symbols-outlined text-[20px]">visibility</span>
|
<span class="material-symbols-outlined text-[20px]">visibility</span>
|
||||||
</button>
|
</button>
|
||||||
|
${
|
||||||
|
app.status !== "Running"
|
||||||
|
? `
|
||||||
|
<button class="text-red-500 hover:text-red-400 transition-colors p-1.5 rounded hover:bg-red-900/20"
|
||||||
|
onclick="openDeleteModal('${app.name}')"
|
||||||
|
title="Eliminar">
|
||||||
|
<span class="material-symbols-outlined text-[20px]">delete</span>
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -643,6 +765,50 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Modal de confirmación para eliminar
|
||||||
|
let appToDelete = null;
|
||||||
|
|
||||||
|
function openDeleteModal(appName) {
|
||||||
|
appToDelete = appName;
|
||||||
|
document.getElementById("delete-app-name").textContent =
|
||||||
|
appName;
|
||||||
|
document
|
||||||
|
.getElementById("delete-modal")
|
||||||
|
.classList.remove("hidden");
|
||||||
|
document.body.style.overflow = "hidden";
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDeleteModal() {
|
||||||
|
appToDelete = null;
|
||||||
|
document.getElementById("delete-modal").classList.add("hidden");
|
||||||
|
document.body.style.overflow = "auto";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function confirmDelete() {
|
||||||
|
if (!appToDelete) return;
|
||||||
|
|
||||||
|
const appName = appToDelete;
|
||||||
|
closeDeleteModal();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/apps/${appName}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
alert(`✅ ${result.data.message}`);
|
||||||
|
loadApps();
|
||||||
|
} else {
|
||||||
|
alert(`❌ Error: ${result.error}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error:", error);
|
||||||
|
alert("❌ Error al eliminar la aplicación");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleMenu() {
|
function toggleMenu() {
|
||||||
const menu = document.getElementById("mobile-menu");
|
const menu = document.getElementById("mobile-menu");
|
||||||
menu.classList.toggle("hidden");
|
menu.classList.toggle("hidden");
|
||||||
|
|||||||
Reference in New Issue
Block a user