Fix TypeError: totalFTE.toFixed is not a function

- Add Number() conversion in overallKPIs calculation to ensure all values are numbers
- Add safeguards in render to handle null/undefined/NaN values before calling .toFixed()
- Prevents crashes when data contains non-numeric values
This commit is contained in:
2026-01-21 13:47:19 +01:00
parent 3c11402e6b
commit 52f851c1f3

View File

@@ -113,6 +113,7 @@ export default function TeamDashboard() {
if (!data) return null; if (!data) return null;
// Sum up total FTE (including min/max bandwidth) // Sum up total FTE (including min/max bandwidth)
// Ensure all values are numbers (handle null/undefined/NaN)
let totalFTE = 0; let totalFTE = 0;
let totalMinFTE = 0; let totalMinFTE = 0;
let totalMaxFTE = 0; let totalMaxFTE = 0;
@@ -121,25 +122,25 @@ export default function TeamDashboard() {
// Aggregate from all teams // Aggregate from all teams
data.teams.forEach(team => { data.teams.forEach(team => {
totalFTE += team.totalEffort; totalFTE += Number(team.totalEffort) || 0;
totalMinFTE += team.minEffort ?? 0; totalMinFTE += Number(team.minEffort) || 0;
totalMaxFTE += team.maxEffort ?? 0; totalMaxFTE += Number(team.maxEffort) || 0;
totalApplicationCount += team.applicationCount; totalApplicationCount += Number(team.applicationCount) || 0;
// Aggregate governance model distribution // Aggregate governance model distribution
Object.entries(team.byGovernanceModel).forEach(([model, count]) => { Object.entries(team.byGovernanceModel).forEach(([model, count]) => {
overallByGovernanceModel[model] = (overallByGovernanceModel[model] || 0) + count; overallByGovernanceModel[model] = (overallByGovernanceModel[model] || 0) + (Number(count) || 0);
}); });
}); });
// Add unassigned // Add unassigned
totalFTE += data.unassigned.totalEffort; totalFTE += Number(data.unassigned.totalEffort) || 0;
totalMinFTE += data.unassigned.minEffort ?? 0; totalMinFTE += Number(data.unassigned.minEffort) || 0;
totalMaxFTE += data.unassigned.maxEffort ?? 0; totalMaxFTE += Number(data.unassigned.maxEffort) || 0;
totalApplicationCount += data.unassigned.applicationCount; totalApplicationCount += Number(data.unassigned.applicationCount) || 0;
Object.entries(data.unassigned.byGovernanceModel).forEach(([model, count]) => { Object.entries(data.unassigned.byGovernanceModel).forEach(([model, count]) => {
overallByGovernanceModel[model] = (overallByGovernanceModel[model] || 0) + count; overallByGovernanceModel[model] = (overallByGovernanceModel[model] || 0) + (Number(count) || 0);
}); });
return { return {
@@ -831,10 +832,10 @@ export default function TeamDashboard() {
Totaal FTE Totaal FTE
</div> </div>
<div className="text-4xl font-bold text-white tracking-tight"> <div className="text-4xl font-bold text-white tracking-tight">
{overallKPIs.totalFTE.toFixed(2)} FTE {(Number(overallKPIs.totalFTE) || 0).toFixed(2)} FTE
</div> </div>
<div className="text-emerald-200 text-sm mt-1"> <div className="text-emerald-200 text-sm mt-1">
Bandbreedte: {overallKPIs.totalMinFTE.toFixed(2)} - {overallKPIs.totalMaxFTE.toFixed(2)} FTE Bandbreedte: {(Number(overallKPIs.totalMinFTE) || 0).toFixed(2)} - {(Number(overallKPIs.totalMaxFTE) || 0).toFixed(2)} FTE
</div> </div>
</div> </div>
@@ -847,7 +848,7 @@ export default function TeamDashboard() {
Application Components Application Components
</div> </div>
<div className="text-4xl font-bold text-white tracking-tight"> <div className="text-4xl font-bold text-white tracking-tight">
{overallKPIs.totalApplicationCount} {Number(overallKPIs.totalApplicationCount) || 0}
</div> </div>
<div className="text-slate-400 text-sm mt-1"> <div className="text-slate-400 text-sm mt-1">
weergegeven weergegeven