feat: Agregar controles de Iniciar/Detener/Reiniciar en panel web
Cambios en el frontend (index.html):
- Cambiar header "Actions" a "Acciones"
- Agregar botones de control según estado de la app:
* Si está Running: botones Detener (rojo) y Reiniciar (amarillo)
* Si está Stopped: botón Iniciar (verde)
* Siempre: botón Ver logs (azul)
- Agregar función controlApp() para llamar a la API
- Diálogo de confirmación antes de ejecutar acciones
- Recarga automática de la tabla después de ejecutar acción
Cambios en el backend (lifecycle.rs):
- Corregir formato de service_name en start_app()
- Corregir formato de service_name en stop_app()
- Corregir formato de service_name en restart_app()
- Ahora usa: siax-app-{app_name}.service en lugar de {app_name}.service
Los botones ahora funcionan correctamente con los servicios systemd
This commit is contained in:
@@ -26,7 +26,7 @@ impl LifecycleManager {
|
|||||||
|
|
||||||
logger.info("Lifecycle", &format!("Iniciando aplicación: {}", app_name));
|
logger.info("Lifecycle", &format!("Iniciando aplicación: {}", app_name));
|
||||||
|
|
||||||
let service_name = format!("{}.service", app_name);
|
let service_name = format!("siax-app-{}.service", app_name);
|
||||||
SystemCtl::start(&service_name)?;
|
SystemCtl::start(&service_name)?;
|
||||||
|
|
||||||
// Actualizar rate limiter
|
// Actualizar rate limiter
|
||||||
@@ -45,7 +45,7 @@ impl LifecycleManager {
|
|||||||
|
|
||||||
logger.info("Lifecycle", &format!("Deteniendo aplicación: {}", app_name));
|
logger.info("Lifecycle", &format!("Deteniendo aplicación: {}", app_name));
|
||||||
|
|
||||||
let service_name = format!("{}.service", app_name);
|
let service_name = format!("siax-app-{}.service", app_name);
|
||||||
SystemCtl::stop(&service_name)?;
|
SystemCtl::stop(&service_name)?;
|
||||||
|
|
||||||
// Actualizar rate limiter
|
// Actualizar rate limiter
|
||||||
@@ -64,7 +64,7 @@ impl LifecycleManager {
|
|||||||
|
|
||||||
logger.info("Lifecycle", &format!("Reiniciando aplicación: {}", app_name));
|
logger.info("Lifecycle", &format!("Reiniciando aplicación: {}", app_name));
|
||||||
|
|
||||||
let service_name = format!("{}.service", app_name);
|
let service_name = format!("siax-app-{}.service", app_name);
|
||||||
SystemCtl::restart(&service_name)?;
|
SystemCtl::restart(&service_name)?;
|
||||||
|
|
||||||
// Actualizar rate limiter
|
// Actualizar rate limiter
|
||||||
|
|||||||
@@ -364,7 +364,7 @@
|
|||||||
<th class="px-6 py-4">Mem %</th>
|
<th class="px-6 py-4">Mem %</th>
|
||||||
<th class="px-6 py-4">Tiempo Activo</th>
|
<th class="px-6 py-4">Tiempo Activo</th>
|
||||||
<th class="px-6 py-4 text-right">
|
<th class="px-6 py-4 text-right">
|
||||||
Actions
|
Acciones
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -557,9 +557,35 @@
|
|||||||
<td class="px-6 py-4 text-sm">-</td>
|
<td class="px-6 py-4 text-sm">-</td>
|
||||||
<td class="px-6 py-4 text-sm text-slate-500">-</td>
|
<td class="px-6 py-4 text-sm text-slate-500">-</td>
|
||||||
<td class="px-6 py-4 text-right">
|
<td class="px-6 py-4 text-right">
|
||||||
<button class="text-slate-400 hover:text-white transition-colors" onclick="window.location.href='/logs'">
|
<div class="flex items-center justify-end gap-2">
|
||||||
<span class="material-symbols-outlined">visibility</span>
|
${
|
||||||
</button>
|
app.status === "Running"
|
||||||
|
? `
|
||||||
|
<button class="text-red-400 hover:text-red-300 transition-colors p-1.5 rounded hover:bg-red-900/20"
|
||||||
|
onclick="controlApp('${app.name}', 'stop')"
|
||||||
|
title="Detener">
|
||||||
|
<span class="material-symbols-outlined text-[20px]">stop</span>
|
||||||
|
</button>
|
||||||
|
<button class="text-yellow-400 hover:text-yellow-300 transition-colors p-1.5 rounded hover:bg-yellow-900/20"
|
||||||
|
onclick="controlApp('${app.name}', 'restart')"
|
||||||
|
title="Reiniciar">
|
||||||
|
<span class="material-symbols-outlined text-[20px]">refresh</span>
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
: `
|
||||||
|
<button class="text-green-400 hover:text-green-300 transition-colors p-1.5 rounded hover:bg-green-900/20"
|
||||||
|
onclick="controlApp('${app.name}', 'start')"
|
||||||
|
title="Iniciar">
|
||||||
|
<span class="material-symbols-outlined text-[20px]">play_arrow</span>
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
<button class="text-blue-400 hover:text-blue-300 transition-colors p-1.5 rounded hover:bg-blue-900/20"
|
||||||
|
onclick="window.location.href='/logs'"
|
||||||
|
title="Ver logs">
|
||||||
|
<span class="material-symbols-outlined text-[20px]">visibility</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
@@ -579,6 +605,44 @@
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function controlApp(appName, action) {
|
||||||
|
const actionNames = {
|
||||||
|
start: "Iniciar",
|
||||||
|
stop: "Detener",
|
||||||
|
restart: "Reiniciar",
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmed = confirm(
|
||||||
|
`¿Estás seguro de ${actionNames[action]} la aplicación "${appName}"?`,
|
||||||
|
);
|
||||||
|
if (!confirmed) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`/api/apps/${appName}/${action}`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
alert(`✅ ${result.data.message}`);
|
||||||
|
// Recargar la lista de apps
|
||||||
|
loadApps();
|
||||||
|
} else {
|
||||||
|
alert(`❌ Error: ${result.error}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error:", error);
|
||||||
|
alert("❌ Error al ejecutar la acció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