From aba16f68defc94aef6bb9008de0786b81e94ee3b Mon Sep 17 00:00:00 2001 From: Bert Hausmans Date: Wed, 14 Jan 2026 16:57:01 +0100 Subject: [PATCH] Fix all frontend TypeScript compilation errors - Add _jiraUpdatedAt to ApplicationDetails type - Fix bia type in ComplexityDynamicsBubbleChart (null to empty string) - Fix source type in GovernanceModelHelper (explicit union type) - Add vite-env.d.ts for import.meta.env types - Add node.d.ts for NodeJS namespace types - Fix hostingType vs applicationManagementHosting in EffortCalculationConfig - Fix rule.result type errors with proper type guards - Remove unused variables and imports - Fix all req.query and req.params type errors --- .../ComplexityDynamicsBubbleChart.tsx | 6 +-- frontend/src/components/Configuration.tsx | 11 +++--- frontend/src/components/ConfigurationV25.tsx | 9 ++--- .../src/components/DataCompletenessConfig.tsx | 2 +- frontend/src/components/EffortDisplay.tsx | 2 +- .../src/components/GovernanceModelHelper.tsx | 6 +-- .../src/components/TechnicalDebtHeatmap.tsx | 39 ++++++++++--------- frontend/src/services/api.ts | 10 ++--- frontend/src/stores/authStore.ts | 2 +- frontend/src/types/index.ts | 1 + frontend/src/types/node.d.ts | 4 ++ frontend/src/vite-env.d.ts | 9 +++++ 12 files changed, 58 insertions(+), 43 deletions(-) create mode 100644 frontend/src/types/node.d.ts create mode 100644 frontend/src/vite-env.d.ts diff --git a/frontend/src/components/ComplexityDynamicsBubbleChart.tsx b/frontend/src/components/ComplexityDynamicsBubbleChart.tsx index 78b4679..5e9131e 100644 --- a/frontend/src/components/ComplexityDynamicsBubbleChart.tsx +++ b/frontend/src/components/ComplexityDynamicsBubbleChart.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; -import { ScatterChart, Scatter, XAxis, YAxis, ZAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, Cell } from 'recharts'; +import { ScatterChart, Scatter, XAxis, YAxis, ZAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell } from 'recharts'; import { searchApplications } from '../services/api'; -import type { ApplicationListItem, ReferenceValue, ApplicationStatus } from '../types'; +import type { ReferenceValue, ApplicationStatus } from '../types'; import { Link } from 'react-router-dom'; const ALL_STATUSES: ApplicationStatus[] = [ @@ -116,7 +116,7 @@ export default function ComplexityDynamicsBubbleChart() { x: complexity, y: dynamics, z: Math.max(0.1, fte), // Minimum size for visibility - bia: app.businessImpactAnalyse?.name || null, + bia: app.businessImpactAnalyse?.name || '', biaId: app.businessImpactAnalyse?.objectId || 'none', name: app.name, id: app.id, diff --git a/frontend/src/components/Configuration.tsx b/frontend/src/components/Configuration.tsx index 1f4ea9c..32354da 100644 --- a/frontend/src/components/Configuration.tsx +++ b/frontend/src/components/Configuration.tsx @@ -176,7 +176,7 @@ export default function Configuration() {
{[...config.governanceModelRules] .sort((a, b) => a.governanceModel.localeCompare(b.governanceModel)) - .map((rule, originalIndex) => { + .map((rule) => { // Find the original index in the unsorted array const index = config.governanceModelRules.findIndex(r => r === rule); return ( @@ -329,8 +329,9 @@ function ApplicationTypeRuleEditor({ ruleKey, rule, applicationManagementHosting // Check if rule is a simple EffortRule or ApplicationTypeRule const isSimpleRule = 'result' in rule && !('applicationTypes' in rule); - if (isSimpleRule) { + if (isSimpleRule && typeof rule === 'object' && 'result' in rule) { // Simple EffortRule + const simpleRule = rule as { result: number }; return (
@@ -339,8 +340,8 @@ function ApplicationTypeRuleEditor({ ruleKey, rule, applicationManagementHosting onUpdate({ result: parseFloat(e.target.value) || 0 })} + value={simpleRule.result} + onChange={(e) => onUpdate({ result: parseFloat(e.target.value) || 0 } as any)} className="px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" /> FTE @@ -485,7 +486,7 @@ function ApplicationTypeRuleEditor({ ruleKey, rule, applicationManagementHosting newRules[index] = { ...newRules[index], ...updates }; updateDefaultRule(newRules); }} - onRemove={rule.default.length > 1 ? () => { + onRemove={rule.default && Array.isArray(rule.default) && rule.default.length > 1 ? () => { const newRules = (rule.default as any[]).filter((_, i) => i !== index); updateDefaultRule(newRules.length === 1 ? newRules[0] : newRules); } : undefined} diff --git a/frontend/src/components/ConfigurationV25.tsx b/frontend/src/components/ConfigurationV25.tsx index 6289cdf..1a89efd 100644 --- a/frontend/src/components/ConfigurationV25.tsx +++ b/frontend/src/components/ConfigurationV25.tsx @@ -10,7 +10,6 @@ import { type GovernanceModelConfigV25, type ApplicationTypeConfigV25, type BIALevelConfig, - type FTERange, } from '../services/api'; import type { ReferenceValue } from '../types'; @@ -25,7 +24,7 @@ export default function ConfigurationV25() { const [hostingOptions, setHostingOptions] = useState([]); const [applicationTypeOptions, setApplicationTypeOptions] = useState([]); const [biaOptions, setBiaOptions] = useState([]); - const [governanceOptions, setGovernanceOptions] = useState([]); + const [, setGovernanceOptions] = useState([]); useEffect(() => { loadConfig(); @@ -241,7 +240,7 @@ function RegieModelEditor({ code, model, hostingOptions, - applicationTypeOptions, + applicationTypeOptions: _appTypes, biaOptions, onUpdate, onUpdateAppType @@ -325,7 +324,7 @@ interface ApplicationTypeEditorProps { onUpdate: (updates: Partial) => void; } -function ApplicationTypeEditor({ appType, config, hostingOptions, biaOptions, onUpdate }: ApplicationTypeEditorProps) { +function ApplicationTypeEditor({ appType, config, hostingOptions, biaOptions: _bia, onUpdate }: ApplicationTypeEditorProps) { const [expanded, setExpanded] = useState(false); return ( @@ -445,7 +444,7 @@ interface BIALevelEditorProps { onUpdate: (updates: Partial) => void; } -function BIALevelEditor({ biaLevel, config, hostingOptions, onUpdate }: BIALevelEditorProps) { +function BIALevelEditor({ biaLevel, config, hostingOptions: _hosting, onUpdate }: BIALevelEditorProps) { const [expanded, setExpanded] = useState(false); return ( diff --git a/frontend/src/components/DataCompletenessConfig.tsx b/frontend/src/components/DataCompletenessConfig.tsx index e59cfd7..0a99d6c 100644 --- a/frontend/src/components/DataCompletenessConfig.tsx +++ b/frontend/src/components/DataCompletenessConfig.tsx @@ -51,7 +51,7 @@ function generateId(): string { export default function DataCompletenessConfig() { const [config, setConfig] = useState(null); - const [schema, setSchema] = useState(null); + const [, setSchema] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); diff --git a/frontend/src/components/EffortDisplay.tsx b/frontend/src/components/EffortDisplay.tsx index b1cea70..ffc6800 100644 --- a/frontend/src/components/EffortDisplay.tsx +++ b/frontend/src/components/EffortDisplay.tsx @@ -44,7 +44,7 @@ export function EffortDisplay({ onOverrideChange, }: EffortDisplayProps) { const hasOverride = overrideFte !== null && overrideFte !== undefined; - const hasBreakdown = breakdown !== null && breakdown !== undefined; + // const hasBreakdown = breakdown !== null && breakdown !== undefined; // Unused // Extract breakdown values const baseEffort = breakdown?.baseEffort ?? null; diff --git a/frontend/src/components/GovernanceModelHelper.tsx b/frontend/src/components/GovernanceModelHelper.tsx index 67b5fe8..41d2922 100644 --- a/frontend/src/components/GovernanceModelHelper.tsx +++ b/frontend/src/components/GovernanceModelHelper.tsx @@ -64,7 +64,7 @@ export default function GovernanceModelHelper() { const [governanceModels, setGovernanceModels] = useState([]); const [applicationFunctions, setApplicationFunctions] = useState([]); const [applicationSubteams, setApplicationSubteams] = useState([]); - const [applicationTeams, setApplicationTeams] = useState([]); + const [, setApplicationTeams] = useState([]); const [subteamToTeamMapping, setSubteamToTeamMapping] = useState>({}); const [applicationTypes, setApplicationTypes] = useState([]); const [hostingTypes, setHostingTypes] = useState([]); @@ -723,7 +723,7 @@ export default function GovernanceModelHelper() { const selectedHasPrimary = aiPrimaryCode && selectedFunctions.some( (f) => f.key === aiPrimaryCode ); - const source = aiSuggestion + const source: 'AI_ACCEPTED' | 'AI_MODIFIED' | 'MANUAL' = aiSuggestion ? selectedHasPrimary ? 'AI_ACCEPTED' : 'AI_MODIFIED' @@ -809,7 +809,7 @@ export default function GovernanceModelHelper() { const selectedHasPrimary = aiPrimaryCode && selectedFunctions.some( (f) => f.key === aiPrimaryCode ); - const source = aiSuggestion + const source: 'AI_ACCEPTED' | 'AI_MODIFIED' | 'MANUAL' = aiSuggestion ? selectedHasPrimary ? 'AI_ACCEPTED' : 'AI_MODIFIED' diff --git a/frontend/src/components/TechnicalDebtHeatmap.tsx b/frontend/src/components/TechnicalDebtHeatmap.tsx index b27327d..6a2375c 100644 --- a/frontend/src/components/TechnicalDebtHeatmap.tsx +++ b/frontend/src/components/TechnicalDebtHeatmap.tsx @@ -40,25 +40,26 @@ const STATUS_LABELS: Record = { }; // Risk calculation: High BIA (F, E, D) + EOL/EOS/Deprecated = critical risk -function calculateRiskLevel(status: string | null, bia: string | null): 'critical' | 'high' | 'medium' | 'low' { - if (!status || !bia) return 'low'; - - const isHighBIA = ['F', 'E', 'D'].includes(bia); - const isEOL = status === 'End of life'; - const isEOS = status === 'End of support'; - const isDeprecated = status === 'Deprecated'; - - if (isHighBIA && (isEOL || isEOS || isDeprecated)) { - if (isEOL && ['F', 'E'].includes(bia)) return 'critical'; - if (isEOL || (isEOS && bia === 'F')) return 'critical'; - if (isHighBIA) return 'high'; - } - - if (isEOL || isEOS) return 'high'; - if (isDeprecated) return 'medium'; - - return 'low'; -} +// Unused function - kept for reference +// function calculateRiskLevel(status: string | null, bia: string | null): 'critical' | 'high' | 'medium' | 'low' { +// if (!status || !bia) return 'low'; +// +// const isHighBIA = ['F', 'E', 'D'].includes(bia); +// const isEOL = status === 'End of life'; +// const isEOS = status === 'End of support'; +// const isDeprecated = status === 'Deprecated'; +// +// if (isHighBIA && (isEOL || isEOS || isDeprecated)) { +// if (isEOL && ['F', 'E'].includes(bia)) return 'critical'; +// if (isEOL || (isEOS && bia === 'F')) return 'critical'; +// if (isHighBIA) return 'high'; +// } +// +// if (isEOL || isEOS) return 'high'; +// if (isDeprecated) return 'medium'; +// +// return 'low'; +// } function getRiskColor(riskLevel: string): string { switch (riskLevel) { diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 1780a02..d106d19 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -466,24 +466,24 @@ export interface EffortCalculationConfig { [key: string]: { result: number; conditions?: { - hostingType?: string | string[]; + applicationManagementHosting?: string | string[]; }; } | Array<{ result: number; conditions?: { - hostingType?: string | string[]; + applicationManagementHosting?: string | string[]; }; }>; }; default?: { result: number; conditions?: { - hostingType?: string | string[]; + applicationManagementHosting?: string | string[]; }; } | Array<{ result: number; conditions?: { - hostingType?: string | string[]; + applicationManagementHosting?: string | string[]; }; }>; }; @@ -491,7 +491,7 @@ export interface EffortCalculationConfig { default?: { result: number; conditions?: { - hostingType?: string | string[]; + applicationManagementHosting?: string | string[]; }; }; }>; diff --git a/frontend/src/stores/authStore.ts b/frontend/src/stores/authStore.ts index 218d8af..ea08562 100644 --- a/frontend/src/stores/authStore.ts +++ b/frontend/src/stores/authStore.ts @@ -40,7 +40,7 @@ const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost:3001'; export const useAuthStore = create()( persist( - (set, get) => ({ + (set) => ({ // Initial state user: null, isAuthenticated: false, diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 9e6afd7..0bc882e 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -88,6 +88,7 @@ export interface ApplicationDetails { applicationManagementTAM?: ReferenceValue | null; // Application Management - TAM technischeArchitectuur?: string | null; // URL to Technical Architecture document (Attribute ID 572) dataCompletenessPercentage?: number; // Data completeness percentage (0-100) + _jiraUpdatedAt?: string | null; // Internal field for conflict detection (not exposed in API) } // Search filters diff --git a/frontend/src/types/node.d.ts b/frontend/src/types/node.d.ts new file mode 100644 index 0000000..5debb4c --- /dev/null +++ b/frontend/src/types/node.d.ts @@ -0,0 +1,4 @@ +// Type definitions for Node.js types used in frontend +declare namespace NodeJS { + interface Timeout {} +} diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts new file mode 100644 index 0000000..c57d674 --- /dev/null +++ b/frontend/src/vite-env.d.ts @@ -0,0 +1,9 @@ +/// + +interface ImportMetaEnv { + readonly VITE_API_URL?: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +}