import React, { useState } from 'react'; import { Plus, Play, Trash2, Clock, Folder, Filter, Calendar, X } from 'lucide-react'; import { BackupJobItem, ClientItem, api, SystemSettingsResponse } from '../services/api'; interface JobsViewProps { jobs: BackupJobItem[]; clients: ClientItem[]; onRefresh: () => void; settings?: SystemSettingsResponse | null; } export const JobsView: React.FC = ({ jobs, clients, onRefresh, settings }) => { const [showModal, setShowModal] = useState(false); const [loading, setLoading] = useState(false); const [formData, setFormData] = useState({ client_id: clients[0]?.id || 0, name: '', source_path: 'C:\\SQLBackups', file_patterns: '*.bak,*.mdf', schedule_cron: '0 2 * * *', keep_daily: 7, keep_weekly: 4, keep_monthly: 12, min_stable_time_seconds: 60, exclude_patterns: '', skip_hidden: false, skip_system: false, skip_readonly: false, sync_deletions: false, }); const handleCreateJob = async (e: React.FormEvent) => { e.preventDefault(); if (!formData.client_id) { alert('Por favor selecciona un cliente'); return; } setLoading(true); try { await api.createJob(formData); setShowModal(false); onRefresh(); } catch (err: any) { alert(`Error creando trabajo: ${err.message}`); } finally { setLoading(false); } }; const handleTrigger = async (job: BackupJobItem) => { try { await api.triggerJob(job.id); alert(`¡Trabajo ${job.job_code} encolado para ejecución inmediata!`); onRefresh(); } catch (err: any) { alert(`Error: ${err.message}`); } }; const handleDelete = async (job: BackupJobItem) => { if (confirm(`¿Eliminar el trabajo de backup ${job.name} (${job.job_code})?`)) { try { await api.deleteJob(job.id); onRefresh(); } catch (err: any) { alert(`Error: ${err.message}`); } } }; const getClientName = (clientId: number) => { const client = clients.find((c) => c.id === clientId); return client ? `${client.name} (${client.client_code})` : `Cliente #${clientId}`; }; return (

Trabajos de Backup Programados

Configuración de rutas de origen Windows, filtros de extensión y políticas de retención

{jobs.map((job) => ( ))} {jobs.length === 0 && ( )}
Job ID Nombre del Trabajo Cliente Asignado Origen en Windows Filtros Retención Horario / Cron Estado Acciones
{job.job_code} {job.name} {job.sync_deletions && ( Réplica )} {getClientName(job.client_id)}
{job.source_path}
{job.file_patterns} {job.keep_daily}d /{' '} {job.keep_weekly}w /{' '} {job.keep_monthly}m {job.schedule_cron} {job.status}
No hay trabajos de backup configurados. Haz clic en "Crear Trabajo de Backup".
{/* Create Job Modal */} {showModal && (

Nuevo Trabajo de Backup

setFormData({ ...formData, name: e.target.value })} />
setFormData({ ...formData, source_path: e.target.value })} />
setFormData({ ...formData, file_patterns: e.target.value })} />
setFormData({ ...formData, schedule_cron: e.target.value })} />
setFormData({ ...formData, min_stable_time_seconds: Number(e.target.value) })} />

Filtros Avanzados (Estilo Karen's Replicator)

setFormData({ ...formData, exclude_patterns: e.target.value })} />
Días (Diario): setFormData({ ...formData, keep_daily: Number(e.target.value) })} />
Semanas (Semanal): setFormData({ ...formData, keep_weekly: Number(e.target.value) })} />
Meses (Mensual): setFormData({ ...formData, keep_monthly: Number(e.target.value) })} />
)}
); };