#!/usr/bin/env ruby # frozen_string_literal: true # tools/orquestador/dashboard/actualizar_estados.rb # ================================================ # Herramienta para actualizar el estado de hitos en el dashboard P2601 # Filosofía: "Menos es más" - herramienta pequeña, específica y reutilizable require 'fileutils' class EstadoHitosManager ESTADOS_VALIDOS = { 'pending' => { nombre: 'Pendiente', clase: 'pending', color: '#eab308' }, 'in-progress' => { nombre: 'En Progreso', clase: 'in-progress', color: '#3b82f6' }, 'completed' => { nombre: 'Completado', clase: 'completed', color: '#22c55e' }, 'blocked' => { nombre: 'Bloqueado', clase: 'blocked', color: '#ef4444' }, 'on-hold' => { nombre: 'En Espera', clase: 'on-hold', color: '#8b5cf6' } }.freeze def initialize(dashboard_path = nil) @dashboard_path = dashboard_path || default_dashboard_path @backup_dir = File.join(File.dirname(@dashboard_path), 'backups') end def default_dashboard_path File.expand_path('../../../../dashboard/index.html', __FILE__) end def listar_hitos puts "📋 LISTADO DE HITOS DISPONIBLES" puts "=" * 50 unless File.exist?(@dashboard_path) puts "❌ Error: No se encuentra el dashboard en #{@dashboard_path}" return false end content = File.read(@dashboard_path) hitos = extraer_hitos(content) if hitos.empty? puts "ℹ️ No se encontraron hitos en el dashboard" return true end puts "🎯 Total de hitos encontrados: #{hitos.size}" puts hitos.each_with_index do |hito, i| estado_info = ESTADOS_VALIDOS[hito[:estado]] || ESTADOS_VALIDOS['pending'] puts " #{i + 1}. [#{hito[:id]}] #{hito[:titulo]}" puts " 📊 Estado actual: #{estado_info[:nombre]} (#{hito[:estado]})" puts " 📅 Fecha: #{hito[:fecha]}" puts " 🏷️ Tags: #{hito[:tags].join(', ')}" if hito[:tags].any? puts end mostrar_resumen_estados(hitos) true end def actualizar_estado(hito_id, nuevo_estado, fecha = nil) puts "🔄 ACTUALIZANDO ESTADO DE HITO" puts "=" * 50 # Validar estado unless ESTADOS_VALIDOS.key?(nuevo_estado) puts "❌ Error: Estado '#{nuevo_estado}' no válido" puts " Estados válidos: #{ESTADOS_VALIDOS.keys.join(', ')}" return false end unless File.exist?(@dashboard_path) puts "❌ Error: No se encuentra el dashboard" return false end # Crear backup create_backup # Leer contenido puts "📖 Leyendo dashboard..." content = File.read(@dashboard_path) # Buscar y actualizar hito puts "🔍 Buscando hito: #{hito_id}" nuevo_contenido, hito_encontrado = actualizar_hito_en_contenido(content, hito_id, nuevo_estado, fecha) unless hito_encontrado puts "❌ Error: No se encontró el hito con ID '#{hito_id}'" puts " Use 'listar' para ver los hitos disponibles" return false end # Guardar cambios puts "💾 Guardando dashboard actualizado..." File.write(@dashboard_path, nuevo_contenido) # Mostrar resultados estado_info = ESTADOS_VALIDOS[nuevo_estado] puts "\n✅ Estado actualizado exitosamente" puts " • Hito: #{hito_id}" puts " • Nuevo estado: #{estado_info[:nombre]}" puts " • Fecha: #{fecha || 'Actualizada automáticamente'}" true end def actualizar_multiples(hitos_estados) puts "🔄 ACTUALIZANDO MÚLTIPLES HITOS" puts "=" * 50 unless File.exist?(@dashboard_path) puts "❌ Error: No se encuentra el dashboard" return false end # Validar todos los estados primero hitos_estados.each do |hito_id, estado| unless ESTADOS_VALIDOS.key?(estado) puts "❌ Error: Estado '#{estado}' no válido para hito '#{hito_id}'" return false end end # Crear backup create_backup # Leer contenido puts "📖 Leyendo dashboard..." content = File.read(@dashboard_path) nuevo_contenido = content.dup # Actualizar cada hito resultados = {} hitos_estados.each do |hito_id, estado| puts "🔍 Actualizando hito: #{hito_id} -> #{estado}" nuevo_contenido, encontrado = actualizar_hito_en_contenido(nuevo_contenido, hito_id, estado) resultados[hito_id] = encontrado end # Guardar cambios puts "💾 Guardando dashboard actualizado..." File.write(@dashboard_path, nuevo_contenido) # Mostrar resultados puts "\n📊 RESULTADOS DE ACTUALIZACIÓN:" exitos = resultados.values.count(true) fallos = resultados.values.count(false) resultados.each do |hito_id, exitoso| emoji = exitoso ? '✅' : '❌' puts " #{emoji} #{hito_id}: #{exitoso ? 'Actualizado' : 'No encontrado'}" end puts "\n📈 RESUMEN:" puts " • Hitós actualizados exitosamente: #{exitos}" puts " • Hitós no encontrados: #{fallos}" exitos > 0 end def mostrar_estados_disponibles puts "🎨 ESTADOS DISPONIBLES" puts "=" * 50 ESTADOS_VALIDOS.each do |codigo, info| puts " • #{codigo}: #{info[:nombre]}" puts " Clase CSS: #{info[:clase]}" puts " Color: #{info[:color]}" puts end true end private def create_backup FileUtils.mkdir_p(@backup_dir) unless Dir.exist?(@backup_dir) timestamp = Time.now.strftime('%Y%m%d_%H%M%S') backup_file = File.join(@backup_dir, "dashboard_estados_#{timestamp}.html") puts "💾 Creando backup en: #{backup_file}" FileUtils.cp(@dashboard_path, backup_file) puts "✅ Backup creado" end def extraer_hitos(content) hitos = [] # Buscar todos los hitos content.scan(/