fix: TS2322 in CalendarPage — typed bootstrap result vars outside JSX
Record<string, T> index type prevents 'error' in narrowing, causing string | T to leak into ReactNode positions. Fix: precompute bootstrapError (string|null) and bootstrapEntries ([string, T][]) before JSX so TypeScript can resolve types correctly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,9 +41,16 @@ interface SeriesMeta {
|
|||||||
assets: string[]
|
assets: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BootstrapSeriesResult {
|
||||||
|
status: string
|
||||||
|
name?: string
|
||||||
|
inserted?: number
|
||||||
|
skipped?: number
|
||||||
|
}
|
||||||
|
|
||||||
interface BootstrapStatus {
|
interface BootstrapStatus {
|
||||||
running: boolean
|
running: boolean
|
||||||
last_result: Record<string, { status: string; inserted: number; skipped: number }> | { error: string } | null
|
last_result: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Constants ─────────────────────────────────────────────────────────────────
|
// ── Constants ─────────────────────────────────────────────────────────────────
|
||||||
@@ -152,8 +159,15 @@ function BootstrapPanel({ onDone }: { onDone: () => void }) {
|
|||||||
return () => clearInterval(iv)
|
return () => clearInterval(iv)
|
||||||
}, [polling])
|
}, [polling])
|
||||||
|
|
||||||
const result = bsStatus.last_result
|
const rawResult = bsStatus.last_result as Record<string, unknown> | null
|
||||||
const hasError = result && 'error' in result
|
const bootstrapError: string | null =
|
||||||
|
rawResult && typeof (rawResult as { error?: unknown }).error === 'string'
|
||||||
|
? (rawResult as { error: string }).error
|
||||||
|
: null
|
||||||
|
const bootstrapEntries: [string, BootstrapSeriesResult][] =
|
||||||
|
rawResult && !bootstrapError
|
||||||
|
? (Object.entries(rawResult) as [string, BootstrapSeriesResult][])
|
||||||
|
: []
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card border-blue-500/30 p-4 space-y-3">
|
<div className="card border-blue-500/30 p-4 space-y-3">
|
||||||
@@ -197,19 +211,19 @@ function BootstrapPanel({ onDone }: { onDone: () => void }) {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{result && !bsStatus.running && (
|
{rawResult && !bsStatus.running && (
|
||||||
hasError ? (
|
bootstrapError ? (
|
||||||
<div className="text-xs text-red-400">Erreur : {'error' in result ? result.error : ''}</div>
|
<div className="text-xs text-red-400">Erreur : {bootstrapError}</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-3 gap-2 mt-2">
|
<div className="grid grid-cols-3 gap-2 mt-2">
|
||||||
{Object.entries(result as Record<string, { status: string; inserted: number; skipped: number; name: string }>).map(([sid, r]) => (
|
{bootstrapEntries.map(([sid, r]) => (
|
||||||
<div key={sid} className={clsx(
|
<div key={sid} className={clsx(
|
||||||
'text-xs px-2 py-1 rounded border',
|
'text-xs px-2 py-1 rounded border',
|
||||||
r.status === 'ok' ? 'border-emerald-700/30 bg-emerald-900/5 text-emerald-300'
|
r.status === 'ok' ? 'border-emerald-700/30 bg-emerald-900/5 text-emerald-300'
|
||||||
: 'border-red-700/30 text-red-400',
|
: 'border-red-700/30 text-red-400',
|
||||||
)}>
|
)}>
|
||||||
<span className="font-mono text-slate-400">{sid}</span>{' '}
|
<span className="font-mono text-slate-400">{sid}</span>{' '}
|
||||||
{r.status === 'ok' ? `+${r.inserted} / skip ${r.skipped}` : 'failed'}
|
{r.status === 'ok' ? `+${r.inserted ?? 0} / skip ${r.skipped ?? 0}` : 'failed'}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user