feat: causal lab
This commit is contained in:
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user