Fix pipeline edit crash: merge defaults with DB configJson

The DB configJson uses different field names than wizard types expect
(e.g., deterministic.rules vs rules, votingEnabled vs juryVotingEnabled).
The ?? operator only guards null/undefined, but configJson is {} (truthy),
so defaults never applied. This caused config.rules.map() to crash with
"Cannot read properties of undefined (reading 'map')".

Fix: spread defaults first then overlay DB values, and add defensive ??
fallbacks in all section components for potentially undefined properties.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 22:55:35 +01:00
parent 7d1c87e938
commit 451b483880
5 changed files with 41 additions and 37 deletions

View File

@@ -26,8 +26,10 @@ export function IntakeSection({ config, onChange, isActive }: IntakeSectionProps
onChange({ ...config, ...updates })
}
const fileRequirements = config.fileRequirements ?? []
const updateFileReq = (index: number, updates: Partial<FileRequirementConfig>) => {
const updated = [...config.fileRequirements]
const updated = [...fileRequirements]
updated[index] = { ...updated[index], ...updates }
onChange({ ...config, fileRequirements: updated })
}
@@ -36,7 +38,7 @@ export function IntakeSection({ config, onChange, isActive }: IntakeSectionProps
onChange({
...config,
fileRequirements: [
...config.fileRequirements,
...fileRequirements,
{
name: '',
description: '',
@@ -49,7 +51,7 @@ export function IntakeSection({ config, onChange, isActive }: IntakeSectionProps
}
const removeFileReq = (index: number) => {
const updated = config.fileRequirements.filter((_, i) => i !== index)
const updated = fileRequirements.filter((_, i) => i !== index)
onChange({ ...config, fileRequirements: updated })
}
@@ -71,7 +73,7 @@ export function IntakeSection({ config, onChange, isActive }: IntakeSectionProps
</p>
</div>
<Switch
checked={config.submissionWindowEnabled}
checked={config.submissionWindowEnabled ?? true}
onCheckedChange={(checked) =>
updateConfig({ submissionWindowEnabled: checked })
}
@@ -85,7 +87,7 @@ export function IntakeSection({ config, onChange, isActive }: IntakeSectionProps
<div className="space-y-2">
<Label>Late Submission Policy</Label>
<Select
value={config.lateSubmissionPolicy}
value={config.lateSubmissionPolicy ?? 'flag'}
onValueChange={(value) =>
updateConfig({
lateSubmissionPolicy: value as IntakeConfig['lateSubmissionPolicy'],
@@ -104,14 +106,14 @@ export function IntakeSection({ config, onChange, isActive }: IntakeSectionProps
</Select>
</div>
{config.lateSubmissionPolicy === 'flag' && (
{(config.lateSubmissionPolicy ?? 'flag') === 'flag' && (
<div className="space-y-2">
<Label>Grace Period (hours)</Label>
<Input
type="number"
min={0}
max={168}
value={config.lateGraceHours}
value={config.lateGraceHours ?? 24}
onChange={(e) =>
updateConfig({ lateGraceHours: parseInt(e.target.value) || 0 })
}
@@ -130,13 +132,13 @@ export function IntakeSection({ config, onChange, isActive }: IntakeSectionProps
</Button>
</div>
{config.fileRequirements.length === 0 && (
{fileRequirements.length === 0 && (
<p className="text-sm text-muted-foreground py-4 text-center">
No file requirements configured. Projects can be submitted without files.
</p>
)}
{config.fileRequirements.map((req, index) => (
{fileRequirements.map((req, index) => (
<Card key={index}>
<CardContent className="pt-4 space-y-3">
<div className="flex items-start gap-3">