fix(commands): dispatch real HTTP plugin commands with offline queue modal and OS validation
parent
a5c4b7b43a
commit
063762e1e4
|
|
@ -16,6 +16,7 @@
|
|||
### Fixed
|
||||
- **Recarga de página en Plugins (`plugins.component`, `plugin-settings.component`)**: Corregido el problema de sincronización reactiva al refrescar directamente (F5) la vista de `/plugins`, añadiendo un estado de carga visual y suscripción a `plugins$` para evitar mostrar prematuramente la pantalla de "No hay plugins instalados".
|
||||
- **Rutas excluidas vacías en ogfreeze (`plugin-settings.component`)**: Corregida la regeneración de scripts cuando el campo de rutas excluidas se deja intencionadamente en blanco; ahora omite de forma limpia el bloque de exclusiones en lugar de forzar los valores predeterminados.
|
||||
- **Ejecución y Validación de Comandos de Plugins (`execute-command.component`)**: Implementado el envío HTTP real de las órdenes de plugins (`POST /api/plugins/...`), validación de estado del SO activo (aviso si están ejecutando Linux u og-live cuando se requiere Windows) y diálogo de confirmación de encolado (`QueueConfirmationModalComponent`) cuando los equipos seleccionados se encuentran apagados o desconectados.
|
||||
|
||||
## [1.15.0] - 2026-10-20
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { AuthService } from '@services/auth.service';
|
|||
import {SoftwareProfilePartitionComponent} from "./software-profile-partition/software-profile-partition.component";
|
||||
import { QueueConfirmationModalComponent } from '../../../../shared/queue-confirmation-modal/queue-confirmation-modal.component';
|
||||
import { ExecuteTaskNowComponent } from './execute-task-now/execute-task-now.component';
|
||||
import { PluginService } from '@services/plugin.service';
|
||||
import { PluginService, PluginCommand } from '@services/plugin.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-execute-command',
|
||||
|
|
@ -219,15 +219,7 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
// Punto de anclaje para ejecución de comandos aportados por plugins
|
||||
const pluginCmd = this.pluginService.findCommand(action);
|
||||
if (pluginCmd) {
|
||||
if (action === 'ogfreeze-freeze') {
|
||||
this.pluginService.toggleFreezeStatus(this.clientData, true);
|
||||
this.toastService.success('Comando de congelación (UWF) enviado correctamente a los equipos seleccionados', 'Plugin Freeze');
|
||||
} else if (action === 'ogfreeze-unfreeze') {
|
||||
this.pluginService.toggleFreezeStatus(this.clientData, false);
|
||||
this.toastService.info('Comando de descongelación (UWF) enviado correctamente a los equipos seleccionados', 'Plugin Freeze');
|
||||
} else {
|
||||
this.toastService.success(`Acción ${pluginCmd.label} ejecutada en los equipos seleccionados`, 'Plugin');
|
||||
}
|
||||
this.executePluginCommand(pluginCmd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -539,4 +531,83 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
private executePluginCommand(pluginCmd: PluginCommand): void {
|
||||
if (!this.clientData || this.clientData.length === 0) {
|
||||
this.toastService.warning('No hay ningún equipo seleccionado para ejecutar esta acción.', pluginCmd.label);
|
||||
return;
|
||||
}
|
||||
|
||||
const requiredOs = (pluginCmd.os || []).map(os => os.toLowerCase());
|
||||
|
||||
// 1. Verificar si hay equipos encendidos en un sistema operativo incompatible (ej. Linux u og-live cuando se requiere Windows)
|
||||
const incompatibleRunningClients = this.clientData.filter(c => {
|
||||
const status = (c.status || '').toLowerCase();
|
||||
const isOnline = status !== 'off' && status !== 'disconnected' && status !== '';
|
||||
if (!isOnline || requiredOs.length === 0) return false;
|
||||
return !requiredOs.some(req => status.includes(req));
|
||||
});
|
||||
|
||||
if (incompatibleRunningClients.length > 0) {
|
||||
const names = incompatibleRunningClients.map(c => c.name || c.ip).join(', ');
|
||||
this.toastService.warning(
|
||||
`Los siguientes equipos no están ejecutando ${requiredOs.join('/')} actualmente: ${names}. La acción requiere que el equipo esté iniciado en el sistema compatible.`,
|
||||
pluginCmd.label
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Verificar si hay equipos apagados o desconectados
|
||||
const offlineClients = this.clientData.filter(c => {
|
||||
const status = (c.status || '').toLowerCase();
|
||||
return !status || status === 'off' || status === 'disconnected';
|
||||
});
|
||||
|
||||
if (offlineClients.length > 0) {
|
||||
const dialogRef = this.dialog.open(QueueConfirmationModalComponent, {
|
||||
width: '400px',
|
||||
data: { clients: this.clientData }
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((queue: boolean | undefined) => {
|
||||
if (queue === undefined) {
|
||||
// El usuario canceló o cerró el modal
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendPluginCommandRequest(pluginCmd, queue);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Todos los equipos están en línea en el sistema operativo correcto
|
||||
this.sendPluginCommandRequest(pluginCmd, false);
|
||||
}
|
||||
|
||||
private sendPluginCommandRequest(pluginCmd: PluginCommand, queue: boolean): void {
|
||||
const defaultSlug = pluginCmd.slug.includes('unfreeze') ? 'unfreeze' : 'freeze';
|
||||
const endpoint = pluginCmd.endpoint || `/api/plugins/ogfreeze/${defaultSlug}`;
|
||||
const cleanEndpoint = endpoint.replace(/^\/api/, '');
|
||||
const url = `${this.baseUrl}${cleanEndpoint}`;
|
||||
|
||||
const clientIds = this.clientData.map(c => c.id || c['@id']);
|
||||
const isFreeze = pluginCmd.slug.includes('freeze') && !pluginCmd.slug.includes('unfreeze');
|
||||
|
||||
this.http.post<any>(url, {
|
||||
clients: clientIds,
|
||||
queue: queue
|
||||
}).subscribe({
|
||||
next: (response) => {
|
||||
this.pluginService.toggleFreezeStatus(this.clientData, isFreeze);
|
||||
const msg = response?.message || (isFreeze
|
||||
? 'Comando de congelación (UWF) procesado correctamente'
|
||||
: 'Comando de descongelación (UWF) procesado correctamente');
|
||||
this.toastService.success(msg, pluginCmd.label);
|
||||
},
|
||||
error: (error) => {
|
||||
const errorMsg = error?.error?.message || error?.error?.['hydra:description'] || 'Error al comunicar con el servidor';
|
||||
this.toastService.error(errorMsg, pluginCmd.label);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue