feat(ux): import compact + preview format Trimiteri + navigatie + scoatere auto_send (5.11)

8 stories TDD (echipa Sonnet, lead orchestreaza). US-001 scoate hold-ul auto_send din mapare
(has_no_auto_send->False, simbol pastrat; cod rezolvat->queued). US-002 scoate bifa auto_send
din UI. US-003 preview pas 3 in format .tabel-trimiteri (STARI_PREVIEW + nota_umana_preview,
fara repr Python; view-model prez). US-004 filtre layout/stil ca referinta + buton Custom.
US-005 navigatie Trimiteri/Mapari sub contoare pe toate paginile. US-006 import <details> nativ
colapsabil. US-007 post-commit reveal (OOB _coada/_status + HX-Trigger). US-008 auto-refresh
dupa actiuni (nudge eliminat).

VERIFY context curat PASS (8/8). /code-review high: 3 buguri reparate (tab nav la self-refresh,
pill Custom valori stale, nota_umana_preview precedenta needs_mapping). 934 passed, 1 skipped.
Backend trimitere + schema NEATINSE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-26 15:16:28 +00:00
parent 412102b9b1
commit 283299ff20
34 changed files with 3079 additions and 389 deletions

View File

@@ -327,6 +327,80 @@ def parse_erori(rar_error: object) -> list[dict]:
return [{"problema": str(data)[:200], "cauza": "", "fix": "", "field": None}]
# ---------------------------------------------------------------------------
# Etichete stari preview import (vocabular DIFERIT de starile de submission)
#
# Starile de preview (ok/needs_review/already_sent/duplicate_in_file) NU
# exista in STARI_SUBMISSION — reutilizarea directa a eticheta_stare/eticheta_scurta
# ridica KeyError. Acest map este sursa de adevar pentru stratul de adaptare din
# _web_compute_preview (routes.py) si pentru template (_preview_rand.html).
# ---------------------------------------------------------------------------
STARI_PREVIEW: dict[str, tuple[str, str]] = {
"ok": ("Gata de trimis", "s-ok"),
"needs_review": ("Verifica valori", "s-needs_review"),
"needs_mapping": ("Cod RAR lipsa", "s-needs_mapping"),
"needs_data": ("Date incomplete", "s-needs_data"),
"already_sent": ("Deja trimis", "s-already_sent"),
"duplicate_in_file": ("Duplicat in fisier", "s-duplicate_in_file"),
}
def nota_umana_preview(status: str, errors: list, flags: list) -> str:
"""Formateaza mesajul uman pentru coloana Note din tabelul de preview import.
Primeste ``errors`` ca lista Python (nu JSON string) — NU pasa la motiv_uman
sau parse_erori care asteapta un JSON string si ar produce repr Python brut
prin fallback ``raw[:160]`` (bug documentat in PRD 5.11 US-003).
Logica de prioritate:
- already_sent / duplicate_in_file -> "" (template le afiseaza separat)
- needs_mapping -> unmapped INAINTE de flags (codul lipsa e motivul real)
- flags non-goale -> primul flag (needs_review: data ambigua etc.)
- errors cu cheie "unmapped" -> "Cod RAR lipsa pentru: COD1, COD2"
- errors cu field+message (needs_data) -> primul mesaj de validare
- altceva -> ""
Fara exceptii. Trunchiat la 200 caractere.
"""
if status in ("already_sent", "duplicate_in_file"):
return ""
# needs_mapping: codul RAR lipseste — prioritizeaza 'unmapped' inaintea flags,
# altfel un rand cu si un flag (ex. VIN numeric) ar afisa textul flag-ului
# si ascunde motivul real (cod lipsa).
if status == "needs_mapping":
for e in errors:
if not isinstance(e, dict):
continue
if "unmapped" in e:
ops = e.get("unmapped") or []
coduri = ", ".join(
o.get("cod_op_service", "") for o in ops if isinstance(o, dict)
)
return ("Cod RAR lipsa pentru: " + coduri if coduri else "Cod RAR lipsa")
if flags:
return str(flags[0])[:200]
for e in errors:
if not isinstance(e, dict):
continue
if "unmapped" in e:
ops = e.get("unmapped") or []
coduri = ", ".join(
o.get("cod_op_service", "") for o in ops if isinstance(o, dict)
)
return (f"Cod RAR lipsa pentru: {coduri}" if coduri else "Cod RAR lipsa")
msg = (
e.get("message")
or e.get("msg")
or e.get("problema")
or e.get("cauza")
or ""
)
if msg:
return str(msg)[:200]
return ""
# ---------------------------------------------------------------------------
# Constante auxiliare (microcopy fix, fara logica)
# ---------------------------------------------------------------------------