// run.jsx — Le Run d'autofill (écran « moment fort »)
//
// CÂBLAGE (2026-08-07, passe « enlever le static ») : l'écran ne raconte que
// le run RÉEL. L'ancienne narration (formulaire nommé d'avance, GES inventés,
// « 47 champs ») était un scénario écrit d'avance — crédible,
// donc dangereux : elle décrivait un travail qui n'avait pas lieu. Désormais
// chaque ligne dérive de l'état du moteur, et chaque compteur est un compte.
// Sans runId : on le dit, on ne simule rien.
const { useState: useStateR, useEffect: useEffectR } = React;
// statut du moteur → fraction de la barre, quand progress_pct n'est pas fourni
const STATUS_P = {
pending: 0.05, parsing: 0.2, inferring: 0.5, filling: 0.85,
awaiting_user: 1, awaiting_review: 1, done: 1, failed: 1,
};
// ordre des phases, pour savoir ce qui est « déjà passé »
const PHASE_ORDER = ["pending", "parsing", "inferring", "filling",
"awaiting_user", "awaiting_review", "done"];
const after = (status, phase) =>
PHASE_ORDER.indexOf(status) >= PHASE_ORDER.indexOf(phase);
/** La narration, dérivée de l'état réel — rien d'écrit d'avance. */
function buildLog(run, t) {
if (!run) return [];
const st = run.status;
const missing = (run.missingFields || []).length;
const lines = [{ icon: "doc", txt: t("J'ouvre votre document…") }];
if (run.detectedFields) lines.push({ icon: "scan", txt: t("{n} champs à remplir détectés.", { n: run.detectedFields }) });
if (after(st, "inferring")) lines.push({ icon: "auto", txt: t("Je puise dans votre profil d'entreprise et votre fiche projet.") });
if (after(st, "filling")) lines.push({ icon: "auto", txt: t("J'inscris ce que je sais déjà, sans rien inventer.") });
if (st === "awaiting_user" && missing) lines.push({ icon: "flag", txt: t("{n} champs ont besoin de vous.", { n: missing }) });
if (st === "awaiting_review") lines.push({ icon: "check", txt: t("Tout est rempli. À vous de relire et de confirmer.") });
if (st === "done") lines.push({ icon: "check", txt: t("{formulaire} rempli et prêt.") });
if (st === "failed") lines.push({ icon: "flag", txt: (run.error || t("Une étape a échoué. Vos réponses sont conservées.")) });
return lines;
}
function RunScreen({ onNext, onBack, runId }) {
const { t } = useLang();
const [run] = useRunPolling(runId);
// Sans run : un écran honnête, pas une simulation.
if (!runId) {
return (
{t("Téléversez d'abord un {formulaire} à l'étape précédente : c'est lui qui lance le travail.")}
{failed ? (run && run.error) || t("Une étape a échoué. Vos réponses sont conservées.") : done ? t("On a complété tout ce qu'on savait. Quelques champs ont besoin de votre confirmation.") : t("Le moteur travaille. Suivez l'avancement en direct ci-dessous.")}