// MDM SORP — AI import wizard (6.8).
const { useState, useEffect, useMemo, useRef, useCallback, createContext, useContext } = React;
function ImportScreen({ navigate }) {
const { t, lang } = useI18n();
const toast = useToast();
const data = window.DATA.importRows;
const [step, setStep] = useState(1); // 0=upload 1=mapping 2=preview 3=dryrun 4=apply
const steps = [
{ id: 0, label: t("import_step_upload") },
{ id: 1, label: t("import_step_mapping") },
{ id: 2, label: t("import_step_preview") },
{ id: 3, label: t("import_step_dryrun") },
{ id: 4, label: t("import_step_apply") },
];
return (
{t("import_title")}
{data.fileName}
{steps.map(s => (
setStep(s.id)}>
{s.id < step ? : s.id + 1}
{s.label}
))}
{step === 0 && setStep(1)}/>}
{step === 1 && setStep(0)} onNext={() => setStep(2)}/>}
{step === 2 && setStep(1)} onNext={() => setStep(3)}/>}
{step === 3 && setStep(2)} onNext={() => { setStep(4); toast("Импорт запущен · 47 строк в очередь обогащения", { onUndo: () => {} }); }}/>}
{step === 4 && navigate("enrichment")}/>}
{lang === "ru" ? "Распознано ИИ" : "AI detected"}
Файл{data.fileName}
Лист{data.sheet}
Тип{data.detected}
ПривязкаSORP-3955
Строк47
Колонок{data.columns.length}
Неуверенных{data.columns.filter(c => c.uncertain).length}
Не сопоставлено{data.columns.filter(c => c.unmapped).length}
{lang === "ru" ? "Что предложил ИИ" : "AI proposals"}
«Артикул производителя» → name_requestedвысокий confidence по образцам — артикулы SKF/NSK
Колонка «Валюта» неполнаяв 3 строках валюта попала в цену («$ 480»). Распарсить?
«Коммент» не сопоставленосохранить как deal_item.notes?
);
}
function StepUpload({ onNext }) {
const { lang, t } = useI18n();
return (
{t("import_drop")}
{t("import_drop_sub")}
Целевая сущность
Недавние импорты
{[
{ name: "Equipment_RFQ_Severstal_2026-05.xlsx", when: "2 мин назад", status: "in-progress" },
{ name: "Suppliers_China_export_2026-04.csv", when: "вчера", status: "done", rows: 142 },
{ name: "Drive_dump_SORP-3929.zip", when: "3 дня назад", status: "done", rows: 18 },
{ name: "AmoCRM_full_export_2026-Q1.csv", when: "10 апр", status: "partial", rows: 1842, err: 14 },
].map((r, i) => (
{r.name}
{r.when}{r.rows ? ` · ${r.rows} строк` : ""}{r.err ? ` · ${r.err} с ошибкой` : ""}
{r.status === "done" &&
Готово}
{r.status === "in-progress" &&
В работе}
{r.status === "partial" &&
Частично}
))}
);
}
function StepMapping({ data, onPrev, onNext }) {
const { t, lang } = useI18n();
return (
<>
{lang === "ru" ? "Маппинг колонок" : "Column mapping"}
Перетащите неверные сопоставления стрелкой
Из файла
В нашу схему
Conf.
{data.columns.map((c, i) => (
{c.src}
{c.unmapped
? <>не сопоставлено>
: <>{c.target}>
}
{c.conf > 0 ? : —}
))}
2 неуверенно · 1 не сопоставлено
>
);
}
function StepPreview({ data, onPrev, onNext }) {
const { t, lang } = useI18n();
return (
<>
{lang === "ru" ? "Предпросмотр после нормализации" : "Preview after normalization"}
Показаны первые 6 из 47
| idx | name_requested | qty | price_buy | currency | lead_days | Статус |
{data.preview.map((r, i) => (
| {r.idx} |
{r.art} |
{r.qty} |
{r.price} |
{r.ccy} |
{r.lead == null ? — : r.lead + "д"} |
{r.status === "ok" && OK}
{r.status === "warn" && {r.note}}
{r.status === "bad" && {r.note}}
|
))}
>
);
}
function StepDryRun({ data, onPrev, onNext }) {
const { t, lang } = useI18n();
const dry = data.dry_run;
return (
<>
Готово к загрузке
41
валидные
В очередь обогащения
5
требуют подтверждения
Найдены проблемы
{[
{ sev: "warn", text: "Строка 3 (32320/Q): валюта пуста → ИИ предложил USD по контексту", action: "Применить" },
{ sev: "warn", text: "Строка 6 (NN3014K/P5): «$ 480» — символ валюты внутри цены → распарсить?", action: "Распарсить" },
{ sev: "bad", text: "Строка 4 (Подшипник 7224): нет поставщика → в очередь сорсинга", action: "Создать запрос" },
{ sev: "warn", text: "12 артикулов уже есть в номенклатуре — связать с существующими?", action: "Связать" },
{ sev: "warn", text: "1 контрагент по TIN совпадает с p_2003 (потенциальный дубль)", action: "Открыть ревью" },
].map((p, i) => (
{p.sev === "bad" ? : }
{p.text}
))}
>
);
}
function StepDone({ onClose }) {
return (
Импорт применён
41 строка загружена · 5 в очереди обогащения · 1 в сорсинге.
);
}
window.ImportScreen = ImportScreen;