feat: causal lab

This commit is contained in:
OpenSquared
2026-06-29 11:35:24 +02:00
parent 7ac7c4c619
commit 394580c8c8

View File

@@ -386,6 +386,7 @@ function TabLibrary({ initialTemplateId }: { initialTemplateId?: number | null }
const [genTheory, setGenTheory] = useState(false) const [genTheory, setGenTheory] = useState(false)
const [editCoefs, setEditCoefs] = useState<Record<string, number>>({}) const [editCoefs, setEditCoefs] = useState<Record<string, number>>({})
const [editEdgesLag, setEdgesLag] = useState<CausalEdge[]>([]) const [editEdgesLag, setEdgesLag] = useState<CausalEdge[]>([])
const [lagDirty, setLagDirty] = useState(false)
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [apiError, setApiError] = useState<string | null>(null) const [apiError, setApiError] = useState<string | null>(null)
const [debugInfo, setDebugInfo] = useState<Record<string, unknown> | null>(null) const [debugInfo, setDebugInfo] = useState<Record<string, unknown> | null>(null)
@@ -414,6 +415,7 @@ function TabLibrary({ initialTemplateId }: { initialTemplateId?: number | null }
Object.entries(t.graph_json?.coefficients || {}).map(([k, v]) => [k, v.value]) Object.entries(t.graph_json?.coefficients || {}).map(([k, v]) => [k, v.value])
)) ))
setEdgesLag(JSON.parse(JSON.stringify(t.graph_json?.edges || []))) setEdgesLag(JSON.parse(JSON.stringify(t.graph_json?.edges || [])))
setLagDirty(false)
} }
async function saveCoefs() { async function saveCoefs() {
@@ -441,6 +443,7 @@ function TabLibrary({ initialTemplateId }: { initialTemplateId?: number | null }
const fresh = await api(`/api/causal-lab/template/${selected.id}`) const fresh = await api(`/api/causal-lab/template/${selected.id}`)
setSelected(fresh) setSelected(fresh)
setEdgesLag(JSON.parse(JSON.stringify(fresh.graph_json?.edges || []))) setEdgesLag(JSON.parse(JSON.stringify(fresh.graph_json?.edges || [])))
setLagDirty(false)
} finally { setSavingLag(false) } } finally { setSavingLag(false) }
} }
@@ -474,6 +477,7 @@ function TabLibrary({ initialTemplateId }: { initialTemplateId?: number | null }
[field]: val === '' ? (field === 'decay_days' ? null : undefined) [field]: val === '' ? (field === 'decay_days' ? null : undefined)
: (field === 'decay_days' ? parseFloat(val) : parseInt(val)), : (field === 'decay_days' ? parseFloat(val) : parseInt(val)),
})) }))
setLagDirty(true)
} }
async function deleteTemplate() { async function deleteTemplate() {
@@ -642,8 +646,12 @@ function TabLibrary({ initialTemplateId }: { initialTemplateId?: number | null }
))} ))}
</div> </div>
<button onClick={saveTemporalParams} disabled={savingLag} <button onClick={saveTemporalParams} disabled={savingLag}
className="mt-4 px-4 py-2 bg-yellow-700 hover:bg-yellow-600 disabled:opacity-50 rounded text-xs font-medium text-white"> className={clsx(
{savingLag ? 'Sauvegarde…' : 'Sauvegarder les paramètres temporels'} 'mt-4 px-4 py-2 rounded text-xs font-medium text-white disabled:opacity-50 transition-all',
lagDirty ? 'bg-amber-600 hover:bg-amber-500 ring-2 ring-amber-400/50 animate-pulse'
: 'bg-slate-700 hover:bg-slate-600'
)}>
{savingLag ? 'Sauvegarde…' : lagDirty ? '⚠ Sauvegarder les paramètres temporels' : 'Paramètres temporels sauvegardés'}
</button> </button>
</div> </div>
)} )}