Merge pull request #20 from sujucu70/claude/check-agent-readiness-status-Exnpc

Claude/check agent readiness status exnpc
This commit is contained in:
sujucu70
2026-02-08 15:43:12 +01:00
committed by GitHub
3 changed files with 82 additions and 28 deletions

View File

@@ -1958,18 +1958,18 @@ function SkillClassificationSection({ drilldownData }: { drilldownData: Drilldow
{quickWins.length > 0 && ( {quickWins.length > 0 && (
<p className="text-xs" style={{ color: COLORS.dark }}> <p className="text-xs" style={{ color: COLORS.dark }}>
<span style={{ color: COLORS.primary }}>🎯 Quick Wins:</span>{' '} <span style={{ color: COLORS.primary }}>🎯 Quick Wins:</span>{' '}
{quickWins.map(s => s.skill).join(' + ')} tienen &gt;60% volumen en T1+T2 {quickWins.map(s => s.skill).join(' + ')} {t('agenticReadiness.roadmapConnection.quickWinsHaveVolume')}
</p> </p>
)} )}
{alerts.length > 0 && ( {alerts.length > 0 && (
<p className="text-xs" style={{ color: COLORS.dark }}> <p className="text-xs" style={{ color: COLORS.dark }}>
<span> Atención:</span>{' '} <span> Atención:</span>{' '}
{alerts.map(s => `${s.skill} tiene ${Math.round(s.tierPcts['HUMAN-ONLY'])}% en HUMAN`).join('; ')} priorizar en Wave 1 {alerts.map(s => `${s.skill} ${t('agenticReadiness.roadmapConnection.hasPercentInHuman', { pct: Math.round(s.tierPcts['HUMAN-ONLY']) })}`).join('; ')} {t('agenticReadiness.roadmapConnection.prioritizeInWave1')}
</p> </p>
)} )}
{quickWins.length === 0 && alerts.length === 0 && ( {quickWins.length === 0 && alerts.length === 0 && (
<p className="text-xs" style={{ color: COLORS.medium }}> <p className="text-xs" style={{ color: COLORS.medium }}>
Distribución equilibrada entre tiers. Revisar colas individuales para priorización. {t('agenticReadiness.roadmapConnection.balancedDistribution')}
</p> </p>
)} )}
</div> </div>
@@ -1979,7 +1979,7 @@ function SkillClassificationSection({ drilldownData }: { drilldownData: Drilldow
} }
// Skills Heatmap/Table (fallback cuando no hay drilldownData) // Skills Heatmap/Table (fallback cuando no hay drilldownData)
function SkillsReadinessTable({ heatmapData }: { heatmapData: HeatmapDataPoint[] }) { function SkillsReadinessTable({ heatmapData, t }: { heatmapData: HeatmapDataPoint[]; t: any }) {
const sortedData = [...heatmapData].sort((a, b) => b.automation_readiness - a.automation_readiness); const sortedData = [...heatmapData].sort((a, b) => b.automation_readiness - a.automation_readiness);
const formatVolume = (v: number) => v >= 1000 ? `${Math.round(v / 1000)}K` : v.toString(); const formatVolume = (v: number) => v >= 1000 ? `${Math.round(v / 1000)}K` : v.toString();
@@ -2808,7 +2808,7 @@ function HumanOnlyByReasonSection({ drilldownData, redFlagConfigs, t }: { drilld
{/* Footer */} {/* Footer */}
<div className="px-5 py-3 bg-gray-50 border-t border-gray-200 text-xs text-gray-500"> <div className="px-5 py-3 bg-gray-50 border-t border-gray-200 text-xs text-gray-500">
Click en una razón para ver las colas afectadas. Priorizar acciones según volumen impactado. {t('agenticReadiness.table.clickToExpandReason')}
</div> </div>
</div> </div>
); );
@@ -2958,11 +2958,11 @@ function PriorityCandidatesSection({ drilldownData, redFlagConfigs, t }: { drill
<div className="px-5 py-3 bg-gray-50 border-t border-gray-200"> <div className="px-5 py-3 bg-gray-50 border-t border-gray-200">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<p className="text-xs text-gray-500"> <p className="text-xs text-gray-500">
<span className="font-medium">{candidateSkills.length}</span> de {drilldownData.length} skills <span className="font-medium">{candidateSkills.length}</span> {t('agenticReadiness.filters.of')} {drilldownData.length} skills
tienen al menos una cola tier AUTOMATE {t('agenticReadiness.roadmapConnection.haveAtLeastOne')}
</p> </p>
<p className="text-xs text-gray-400"> <p className="text-xs text-gray-400">
Haz clic en un skill para ver las colas individuales con desglose de score {t('agenticReadiness.table.clickToExpand')}
</p> </p>
</div> </div>
</div> </div>
@@ -3486,11 +3486,11 @@ function SkillsToOptimizeSection({ drilldownData }: { drilldownData: DrilldownDa
> >
{showAll ? ( {showAll ? (
<> <>
<ChevronUp className="w-3 h-3" /> Mostrar menos <ChevronUp className="w-3 h-3" /> {t('agenticReadiness.roadmapConnection.showLess')}
</> </>
) : ( ) : (
<> <>
<ChevronDown className="w-3 h-3" /> Ver todos ({skillsToOptimize.length}) <ChevronDown className="w-3 h-3" /> {t('agenticReadiness.roadmapConnection.viewAll', { count: skillsToOptimize.length })}
</> </>
)} )}
</button> </button>
@@ -3501,7 +3501,7 @@ function SkillsToOptimizeSection({ drilldownData }: { drilldownData: DrilldownDa
} }
// v3.6: Sección de conexión con Roadmap // v3.6: Sección de conexión con Roadmap
function RoadmapConnectionSection({ drilldownData }: { drilldownData: DrilldownDataPoint[] }) { function RoadmapConnectionSection({ drilldownData, t }: { drilldownData: DrilldownDataPoint[]; t: any }) {
// Extraer todas las colas // Extraer todas las colas
const allQueues = drilldownData.flatMap(skill => const allQueues = drilldownData.flatMap(skill =>
skill.originalQueues.map(q => ({ ...q, skillName: skill.skill })) skill.originalQueues.map(q => ({ ...q, skillName: skill.skill }))
@@ -3584,27 +3584,27 @@ function RoadmapConnectionSection({ drilldownData }: { drilldownData: DrilldownD
<div className="rounded-lg p-4 border" style={{ backgroundColor: '#f0fdf4', borderColor: '#86efac' }}> <div className="rounded-lg p-4 border" style={{ backgroundColor: '#f0fdf4', borderColor: '#86efac' }}>
<div className="flex items-center gap-2 mb-2"> <div className="flex items-center gap-2 mb-2">
<span className="text-lg"></span> <span className="text-lg"></span>
<span className="font-bold text-emerald-800">QUICK WINS INMEDIATOS (sin Wave 1)</span> <span className="font-bold text-emerald-800">{t('agenticReadiness.roadmapConnection.quickWinsTitle')}</span>
</div> </div>
<div className="space-y-1 text-sm text-emerald-700"> <div className="space-y-1 text-sm text-emerald-700">
<p> <p>
<strong>{automateQueues.length} colas AUTOMATE</strong> con{' '} <strong>{t('agenticReadiness.roadmapConnection.automateQueues', { count: automateQueues.length })}</strong> {t('agenticReadiness.roadmapConnection.with')}{' '}
<strong>{(automateVolume / 1000).toFixed(0)}K interacciones/mes</strong> <strong>{(automateVolume / 1000).toFixed(0)}K {t('agenticReadiness.roadmapConnection.interactionsPerMonth')}</strong>
</p> </p>
<p <p
className="cursor-help" className="cursor-help"
title={`Cálculo: ${automateVolume.toLocaleString()} int × 12 meses × 70% contención × €2.18/int = €${(annualSavingsAutomate / 1000000).toFixed(1)}M`} title={t('agenticReadiness.roadmapConnection.calculationNote', { volume: automateVolume.toLocaleString(), rate: 70, type: t('agenticReadiness.roadmapConnection.containment'), cpi: '2.18' })}
> >
Ahorro potencial: <strong className="text-emerald-800">{(annualSavingsAutomate / 1000000).toFixed(1)}M/año</strong> {t('agenticReadiness.roadmapConnection.savingsPotential')} <strong className="text-emerald-800">{(annualSavingsAutomate / 1000000).toFixed(1)}M{t('agenticReadiness.roadmapConnection.perYear')}</strong>
<span className="text-emerald-600 ml-1 text-xs">(70% contención × 2.18/int)</span> <span className="text-emerald-600 ml-1 text-xs">(70% {t('agenticReadiness.roadmapConnection.containment')} × 2.18{t('agenticReadiness.roadmapConnection.perInt')})</span>
</p> </p>
{skillsWithAutomate.length > 0 && ( {skillsWithAutomate.length > 0 && (
<p> <p>
Skills: <strong>{skillsWithAutomate.join(', ')}</strong> {t('agenticReadiness.roadmapConnection.skills')} <strong>{skillsWithAutomate.join(', ')}</strong>
</p> </p>
)} )}
<p className="pt-1 text-emerald-600 italic text-xs"> <p className="pt-1 text-emerald-600 italic text-xs">
Alineado con Wave 4 del Roadmap. Pueden implementarse en paralelo a Wave 1. {t('agenticReadiness.roadmapConnection.alignedWithWave4')}
</p> </p>
</div> </div>
</div> </div>
@@ -3616,35 +3616,35 @@ function RoadmapConnectionSection({ drilldownData }: { drilldownData: DrilldownD
<div className="flex items-center gap-2 mb-2"> <div className="flex items-center gap-2 mb-2">
<span className="text-lg">🔧</span> <span className="text-lg">🔧</span>
<span className="font-bold" style={{ color: COLORS.dark }}> <span className="font-bold" style={{ color: COLORS.dark }}>
WAVE 1-3: FOUNDATION ASSIST ({assistQueues.length} colas) {t('agenticReadiness.roadmapConnection.wave13Title', { count: assistQueues.length })}
</span> </span>
</div> </div>
<div className="space-y-1 text-sm" style={{ color: COLORS.dark }}> <div className="space-y-1 text-sm" style={{ color: COLORS.dark }}>
<p> <p>
<strong>{(assistVolume / 1000).toFixed(0)}K interacciones/mes</strong> en tier ASSIST <strong>{(assistVolume / 1000).toFixed(0)}K {t('agenticReadiness.roadmapConnection.interactionsPerMonth')}</strong> {t('agenticReadiness.roadmapConnection.inTierAssist')}
</p> </p>
{skillsNeedingWave1.length > 0 && ( {skillsNeedingWave1.length > 0 && (
<p> <p>
<strong>Foco Wave 1:</strong> Reducir transfer en{' '} <strong>{t('agenticReadiness.roadmapConnection.focusWave1')}</strong> {t('agenticReadiness.roadmapConnection.reduceTransferIn')}{' '}
<strong>{skillsNeedingWave1.map(s => s.skill).join(' & ')}</strong>{' '} <strong>{skillsNeedingWave1.map(s => s.skill).join(' & ')}</strong>{' '}
({Math.round(skillsNeedingWave1[0]?.humanPct || 0)}% HUMAN) ({Math.round(skillsNeedingWave1[0]?.humanPct || 0)}% HUMAN)
</p> </p>
)} )}
<p <p
className="cursor-help" className="cursor-help"
title={`Cálculo: ${assistVolume.toLocaleString()} int × 12 meses × 30% deflection × €0.83/int`} title={t('agenticReadiness.roadmapConnection.calculationNote', { volume: assistVolume.toLocaleString(), rate: 30, type: t('agenticReadiness.roadmapConnection.deflection'), cpi: '0.83' })}
> >
<strong>Potencial con Copilot:</strong>{' '} <strong>{t('agenticReadiness.roadmapConnection.potentialWithCopilot')}</strong>{' '}
<strong style={{ color: COLORS.primary }}> <strong style={{ color: COLORS.primary }}>
{potentialAnnualAssist >= 1000000 {potentialAnnualAssist >= 1000000
? `${(potentialAnnualAssist / 1000000).toFixed(1)}M` ? `${(potentialAnnualAssist / 1000000).toFixed(1)}M`
: `${(potentialAnnualAssist / 1000).toFixed(0)}K` : `${(potentialAnnualAssist / 1000).toFixed(0)}K`
}/año }{t('agenticReadiness.roadmapConnection.perYear')}
</strong> </strong>
<span className="ml-1 text-xs" style={{ color: COLORS.medium }}>(30% deflection × 0.83/int)</span> <span className="ml-1 text-xs" style={{ color: COLORS.medium }}>(30% {t('agenticReadiness.roadmapConnection.deflection')} × 0.83{t('agenticReadiness.roadmapConnection.perInt')})</span>
</p> </p>
<p className="pt-1 italic text-xs" style={{ color: COLORS.medium }}> <p className="pt-1 italic text-xs" style={{ color: COLORS.medium }}>
Requiere Wave 1 (Foundation) para habilitar Copilot en Wave 3 {t('agenticReadiness.roadmapConnection.requiresWave1')}
</p> </p>
</div> </div>
</div> </div>
@@ -3745,7 +3745,7 @@ export function AgenticReadinessTab({ data, onTabChange }: AgenticReadinessTabPr
</> </>
) : ( ) : (
/* Fallback a tabla por Línea de Negocio si no hay drilldown data */ /* Fallback a tabla por Línea de Negocio si no hay drilldown data */
<SkillsReadinessTable heatmapData={data.heatmapData} /> <SkillsReadinessTable heatmapData={data.heatmapData} t={t} />
)} )}
{/* Link al Roadmap */} {/* Link al Roadmap */}

View File

@@ -1103,6 +1103,33 @@
"viewRoadmapTab": "View Roadmap tab for detailed plan", "viewRoadmapTab": "View Roadmap tab for detailed plan",
"viewRoadmapLink": "View Roadmap tab for detailed plan →" "viewRoadmapLink": "View Roadmap tab for detailed plan →"
}, },
"roadmapConnection": {
"quickWinsTitle": "IMMEDIATE QUICK WINS (without Wave 1)",
"automateQueues": "{{count}} AUTOMATE queues",
"with": "with",
"interactionsPerMonth": "interactions/month",
"savingsPotential": "Savings potential:",
"perYear": "/year",
"containment": "containment",
"perInt": "/int",
"skills": "Skills:",
"alignedWithWave4": "→ Aligned with Roadmap Wave 4. Can be implemented in parallel to Wave 1.",
"wave13Title": "WAVE 1-3: FOUNDATION → ASSIST ({{count}} queues)",
"inTierAssist": "in tier ASSIST",
"focusWave1": "Wave 1 Focus:",
"reduceTransferIn": "Reduce transfer in",
"potentialWithCopilot": "Potential with Copilot:",
"deflection": "deflection",
"requiresWave1": "→ Requires Wave 1 (Foundation) to enable Copilot in Wave 3",
"calculationNote": "Calculation: {{volume}} int × 12 months × {{rate}}% {{type}} × €{{cpi}}/int",
"quickWinsHaveVolume": "have >60% volume in T1+T2",
"hasPercentInHuman": "has {{pct}}% in HUMAN",
"prioritizeInWave1": "→ prioritize in Wave 1",
"balancedDistribution": "Balanced distribution across tiers. Review individual queues for prioritization.",
"haveAtLeastOne": "have at least one tier AUTOMATE queue",
"showLess": "Show less",
"viewAll": "View all ({{count}})"
},
"factorsExtended": { "factorsExtended": {
"volumeMethodology": "Score = normalized log10(Volume). >5000 → 10, <100 → 2", "volumeMethodology": "Score = normalized log10(Volume). >5000 → 10, <100 → 2",
"volumeBenchmark": "Positive ROI requires >500/month", "volumeBenchmark": "Positive ROI requires >500/month",

View File

@@ -1134,6 +1134,33 @@
"viewRoadmapTab": "Ver pestaña Roadmap para plan detallado", "viewRoadmapTab": "Ver pestaña Roadmap para plan detallado",
"viewRoadmapLink": "Ver pestaña Roadmap para plan detallado →" "viewRoadmapLink": "Ver pestaña Roadmap para plan detallado →"
}, },
"roadmapConnection": {
"quickWinsTitle": "QUICK WINS INMEDIATOS (sin Wave 1)",
"automateQueues": "{{count}} colas AUTOMATE",
"with": "con",
"interactionsPerMonth": "interacciones/mes",
"savingsPotential": "Ahorro potencial:",
"perYear": "/año",
"containment": "contención",
"perInt": "/int",
"skills": "Skills:",
"alignedWithWave4": "→ Alineado con Wave 4 del Roadmap. Pueden implementarse en paralelo a Wave 1.",
"wave13Title": "WAVE 1-3: FOUNDATION → ASSIST ({{count}} colas)",
"inTierAssist": "en tier ASSIST",
"focusWave1": "Foco Wave 1:",
"reduceTransferIn": "Reducir transfer en",
"potentialWithCopilot": "Potencial con Copilot:",
"deflection": "deflection",
"requiresWave1": "→ Requiere Wave 1 (Foundation) para habilitar Copilot en Wave 3",
"calculationNote": "Cálculo: {{volume}} int × 12 meses × {{rate}}% {{type}} × €{{cpi}}/int",
"quickWinsHaveVolume": "tienen >60% volumen en T1+T2",
"hasPercentInHuman": "tiene {{pct}}% en HUMAN",
"prioritizeInWave1": "→ priorizar en Wave 1",
"balancedDistribution": "Distribución equilibrada entre tiers. Revisar colas individuales para priorización.",
"haveAtLeastOne": "tienen al menos una cola tier AUTOMATE",
"showLess": "Mostrar menos",
"viewAll": "Ver todos ({{count}})"
},
"factorsExtended": { "factorsExtended": {
"volumeMethodology": "Score = log10(Volumen) normalizado. >5000 → 10, <100 → 2", "volumeMethodology": "Score = log10(Volumen) normalizado. >5000 → 10, <100 → 2",
"volumeBenchmark": "ROI positivo requiere >500/mes", "volumeBenchmark": "ROI positivo requiere >500/mes",