Files
rar-autopass/docs/prd/prd-5.22-ui-compact-trimiteri-reguli-fix-chips.md
Claude Agent 5a2c976d46 feat(web): UI compact Trimiteri + bara bulk contextuala + fix buton "+" editor (PRD 5.22)
Trimiteri desktop = tabel grid cu header, un rand per trimitere: status =
bulina cu tooltip, mediu = litera T/P, multi-cod = primul cod + badge +N,
sub-linie de eroare cu textul brut RAR doar pe error/needs_data. Mobil:
2 linii prin grid-areas, fara header. Actiunile bulk apar doar la selectie
(bara contextuala cu contor + texte explicite). Mapari: exemplu concret in
loc de descriere la Reguli automate.

Fix buton "+" chips (nu facea nimic, fara eroare): hx-disabled-elt="find
button" mostenit de la form-ul parinte crapa htmx inainte de request ->
hx-disabled-elt="this" explicit pe butoanele chips; separat, no-op-urile
silentioase din post_form_chips au acum mesaje (cod invalid/duplicat) si
confirmare cu chip evidentiat la succes.

Suita: 1622 passed. Verify E2E in browser (desktop 1280 + mobil 390).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:27:42 +00:00

13 KiB

PRD 5.22 — UI compact Trimiteri + bara contextuala "Aplica cod" + exemplu Reguli automate + fix buton "+" editor import

Stare: inchis

Mockup aprobat de utilizator (artifact 6efc43e0, v2, 2026-07-07). Decizii inchise: tabel desktop pe un rand cu header; status = bulina + tooltip; mediu = litera T/P; multi-cod = primul cod + badge +N cu tooltip; sub-linie de problema = textul brut al erorii, mono, trunchiat, doar pe erori; bara "Aplica cod" contextuala la selectie; Reguli automate = exemplu concret in loc de paragraf descriptiv; fix no-op silentios la butonul "+" din editorul de import.

1. Obiectiv

Patru imbunatatiri UI/UX aprobate pe mockup: (a) lista Trimiteri devine tabel compact pe un singur rand pe desktop, cu header de coloane si semnalizare compacta status/mediu; (b) actiunea bulk "Aplica cod" devine bara contextuala vizibila doar la selectie; (c) sectiunea "Reguli automate (text)" din Mapari isi inlocuieste descrierea cu un exemplu concret; (d) butonul "+" din editorul de prestatii (import) nu mai esueaza silentios — feedback vizibil la succes si la refuz.

2. Non-Goals (anti scope-creep)

  • NU se schimba logica backend a bulk-fix (POST /trimiteri/bulk-fix) — doar prezentarea.
  • NU se schimba masina de stari submissions, filtrele, paginarea sau modalul de detaliu.
  • NU se adauga functionalitate noua la regulile text (/mapari/reguli-text) — doar microcopy.
  • NU se redeseneaza restul editorului de rand din import (doar zona chips "+").
  • NU se ating API v1, worker-ul sau schema DB.

3. Stories atomice

US-001: Fix buton "+" chips prestatii — feedback la refuz si la succes

Ca operator care editeaza un rand de import vreau ca apasarea pe "+" sa aiba mereu un efect vizibil pentru ca azi codul invalid sau duplicat produce un raspuns identic, fara niciun mesaj ("nu se intampla nimic").

  • Depinde de: —
  • Fisiere: app/web/routes.py (post_form_chips), app/web/templates/_chips_prestatii.html, tests/test_web_corectie_prestatii.py (~3 fisiere)
  • Test intai (RED): tests/test_web_corectie_prestatii.pytest_add_cod_duplicat_afiseaza_mesaj, test_add_cod_invalid_afiseaza_mesaj, test_add_cod_reusit_marcheaza_chip_nou
  • Acceptance criteria:
    • Ramurile add, add_extra, add_flat din post_form_chips: cod care nu trece verificarea in nomenclator_rar → mesaj de eroare in fragmentul re-randat ("Cod necunoscut in nomenclator"), nu raspuns identic.
    • Cod deja prezent in lista (dedup) → mesaj "X este deja in lista — nu a fost adaugat inca o data", pe TOATE cele 3 ramuri.
    • Adaugare reusita → chip-ul nou primeste clasa de evidentiere (chip-nou, outline verde) + mesaj de confirmare "X adaugat" (aria-live pentru SR).
    • Mesajele traiesc in fragmentul _chips_prestatii.html (swap outerHTML pe #chips-section) si dispar la urmatoarea actiune reusita.
    • python3 -m pytest -q verde.
  • Verificare E2E: browser pe import → Editeaza rand → alege cod deja adaugat → "+" → mesaj rosu vizibil; alege cod nou → "+" → chip verde evidentiat + mesaj.

US-002: Reguli automate — exemplu concret in loc de descriere

Ca utilizator al paginii Mapari vreau sa vad un exemplu de regula in loc de un paragraf explicativ pentru ca exemplul arata direct formatul si scuteste cititul.

  • Depinde de: —
  • Fisiere: app/web/templates/_mapari.html, tests/test_web_mapari_text_rules.py (~2 fisiere)
  • Test intai (RED): tests/test_web_mapari_text_rules.pytest_sectiune_reguli_afiseaza_exemplu_nu_descriere
  • Acceptance criteria:
    • Textul descriptiv din capul sectiunii "Reguli automate (text)" (inclusiv empty-state) e inlocuit cu un singur exemplu formatat: Daca operatia contine "verificare" → Cod RAR = OE-2 Intretinere si revizie, cu pattern-ul si codul evidentiate vizual (chip warn / chip accent, ca in mockup).
    • Nicio schimbare functionala la tabel, adaugare, preview sau stergere reguli.
    • python3 -m pytest -q verde.
  • Verificare E2E: browser pe Mapari → sectiunea Reguli automate afiseaza exemplul.

US-003: View-model rand trimitere — coduri multiple + eroare bruta

Ca dashboard vreau ca randul de trimitere sa expuna lista completa de coduri RAR si textul brut al erorii pentru ca UI-ul compact afiseaza primul cod +N (tooltip cu toate) si sub-linia de eroare cu mesajul RAR, nu eticheta explicativa.

  • Depinde de: —
  • Fisiere: app/payload_view.py, app/web/routes.py (_submission_row_view), tests/test_payload_view.py, tests/test_web_submissions.py (~4 fisiere)
  • Test intai (RED): tests/test_payload_view.pytest_coduri_rar_lista_ordonata_dedup, test_coduri_rar_gol_fara_prestatii; tests/test_web_submissions.pytest_rand_expune_eroare_bruta_doar_pe_error
  • Acceptance criteria:
    • prezentare_din_payload intoarce camp nou coduri_rar: lista ordonata, dedup, a codurilor RAR (cod_prestatie) din TOATE prestatiile (lista goala cand nu exista); campurile existente raman neschimbate (compatibilitate).
    • _submission_row_view expune eroare_bruta: mesajul RAR brut cand exista (rar_error → mesajul serverului, ex. ORA-12899...), altfel motiv scurt; sir gol pe stari fara problema. needs_mapping NU produce eroare_bruta (informatia "nemapat" traieste in coloana Cod RAR).
    • python3 -m pytest -q verde.
  • Verificare E2E: — (acoperit de US-004).

US-004: Trimiteri desktop — tabel cu header, un rand per trimitere

Ca operator pe desktop vreau trimiterile intr-un tabel compact cu header de coloane pentru ca este loc pe orizontala si scanez mai repede o lista pe un rand.

  • Depinde de: US-003
  • Fisiere: app/web/templates/_submissions.html, app/web/templates/base.html (CSS), tests/test_web_submissions_layout.py (~3 fisiere)
  • Test intai (RED): tests/test_web_submissions_layout.pytest_desktop_header_coloane, test_status_bulina_cu_tooltip, test_mediu_litera_t_p, test_multicod_badge_plus_n, test_sublinie_eroare_bruta_doar_pe_error
  • Acceptance criteria:
    • Pe desktop (>= breakpoint existent), lista devine tabel/grid cu header: (checkbox) · Vehicul · Cod RAR · Operatie · Data · Status · Mediu · (actiuni). Un rand per trimitere, fara wrap; operatia primeste ellipsis.
    • Status = DOAR bulina colorata (culorile claselor s-* existente), nume stare complet in title (tooltip); coloana are headerul "Status".
    • Mediu = litera in coloana proprie cu header "Mediu": P alb pe fundal --err (productie), T contur discret (testare); title cu numele complet.
    • Mai multe coduri: primul cod + badge +N cu title care listeaza toate codurile din coduri_rar; un singur cod → fara badge; niciun cod → nemapat.
    • Sub-linia de problema apare DOAR cand eroare_bruta e ne-goala: text mono, --fs-xs, culoare --err, un singur rand cu text-overflow:ellipsis, title cu textul complet.
    • Comportamente pastrate: click pe rand → modal detaliu; checkbox doar pe gestionabil; buton "Trimite" doar pe tinut; paginare/filtre neatinse.
    • python3 -m pytest -q verde.
  • Verificare E2E: browser HTMX pe http://localhost:8010/ (desktop 1280px) — randuri pe o singura linie, header vizibil, tooltip-uri corecte.

US-005: Trimiteri mobil — bulina status + litera mediu

Ca operator pe mobil vreau aceleasi semnale compacte (bulina + T/P) pe lista de 2 linii pentru ca pill-urile cu text ocupa spatiu inutil pe ecran mic.

  • Depinde de: US-004
  • Fisiere: app/web/templates/_submissions.html, app/web/templates/base.html (media query), tests/test_web_submissions_layout.py (~3 fisiere)
  • Test intai (RED): tests/test_web_submissions_layout.pytest_mobil_pastreaza_doua_linii_cu_bulina_si_litera
  • Acceptance criteria:
    • Sub breakpoint, randul revine la 2 linii (placuta / cod·operatie·data), iar in dreapta stau litera de mediu + bulina de status (+ butonul "Trimite" pe tinute).
    • Fara header de tabel pe mobil; fara scroll orizontal la 390px.
    • python3 -m pytest -q verde.
  • Verificare E2E: browser la 390px — lista lizibila, fara overflow orizontal.

US-006: Bara contextuala "Aplica cod" — vizibila doar la selectie

Ca operator vreau ca actiunile bulk sa apara doar cand am selectat randuri, cu text explicit pentru ca butonul permanent "Aplica cod" fara context e confuz.

  • Depinde de: US-004
  • Fisiere: app/web/templates/_submissions.html, app/web/templates/base.html (CSS + JS numarare selectie), tests/test_web_bulk_fix.py (~3 fisiere)
  • Test intai (RED): tests/test_web_bulk_fix.pytest_bara_bulk_ascunsa_implicit, test_bara_bulk_texte_explicite
  • Acceptance criteria:
    • Inputul de cod + "Aplica cod" + "Sterge selectate" dispar din capul listei; apar intr-o bara contextuala (stil accent, ca in mockup) randata ascunsa si afisata prin JS cand >= 1 checkbox e bifat; dispare la deselectare.
    • Bara contine: contor "N selectate", input cod RAR, buton "Aplica acest cod la N randuri", separator, buton "Sterge N randuri", actiune "Deselecteaza"; N se actualizeaza la fiecare bifare (JS, fara roundtrip).
    • Sub bara: hint pe un rand — "Aplica codul RAR doar operatiilor fara cod din randurile selectate, apoi le repune in coada."
    • Endpoint-urile, CSRF, hx-confirm pe stergere si hx-disinherit raman functional identice; bulk_message se afiseaza ca acum.
    • Starea barei supravietuieste re-randarii fragmentului (re-evaluare la htmx:afterSwap — dupa swap selectia se pierde, bara se ascunde).
    • python3 -m pytest -q verde.
  • Verificare E2E: browser — capul listei curat; bifez 2 randuri blocate → bara apare cu "2 selectate"; aplic cod → lista se reincarca, bara dispare, sumar vizibil.

4. Riscuri

  • Tabel vs. lista pe acelasi fragment: _submissions.html e folosit si de paginare/filtre/OOB — orice schimbare de structura trebuie sa pastreze id-urile (#submissions-wrap, #bulk-trimiteri, OOB-urile). Mitigare: pastram form-ul si id-urile existente, schimbam doar interiorul listei; testele de layout existente (test_web_submissions_layout.py) ruleaza inainte si dupa.
  • rar_error brut poate contine detalii tehnice lungi: afisare pe un rand cu ellipsis + title; nu se logheaza/expune nimic nou (textul exista deja in modal).
  • JS-ul de numarare selectie ruleaza peste randuri re-randate de HTMX: legare prin delegare pe container, nu pe noduri (altfel handler-ii mor la swap).
  • Doua semnale rotunde alaturate pe mobil (bulina status + litera mediu): litera are forma/continut diferit de bulina — validat in mockup; daca in practica se confunda, fallback aprobat: mediu doar pe randurile de productie.

5. Intrebari deschise

— (toate inchise prin mockup v2 aprobat)

6. Valuri de executie (graful de dependente)

Val 1: [US-001] [US-002] [US-003]   ← fara dependente, fisiere disjuncte → paralel
Val 2: [US-004]                     ← deblocat de US-003
Val 3: [US-005] [US-006]            ← deblocate de US-004; ating aceleasi fisiere → secvential intre ele

Raport VERIFY

Verdict: PASS — 2026-07-07, E2E in browser (Playwright, uvicorn pe DB temporar, 7 trimiteri seedate: sent/queued/held/needs_mapping/error, test+prod, multi-cod).

  • Desktop 1280px: header Vehicul/Cod RAR/Operatie/Data/Status/Mediu; un rand per trimitere; bulina colorata cu title; P fill rosu / T contur; OE-1 +2 cu tooltip; sub-linie ORA-12899... mono trunchiata doar pe rândul error; nemapat italic fara sub-linie.
  • Bara bulk: ascunsa implicit; la 2 checkbox-uri → "2 selectate · Aplica acest cod la 2 randuri | Sterge 2 randuri | Deselecteaza" + hint; aplicat OE-2 → ambele randuri → queued, bara dispare.
  • Mapari: exemplul "Daca operatia contine «verificare» → Cod RAR = OE-2 Intretinere si revizie" inlocuieste descrierea.
  • Chips "+": adaugare OE-1 → chip evidentiat (chip-nou) + "OE-1 adaugat."; duplicat → "OE-1 este deja in lista — nu a fost adaugat inca o data."; select gol → "Selecteaza un cod RAR din lista".
  • Mobil 390px: fara header, 2 linii, T/P + bulina in dreapta, fara scroll orizontal.
  • Suita completa: 1622 passed, 1 skipped.

Cauza-radacina REALA a bug-ului "+" (gasita LA VERIFY, nu in analiza statica): form-urile parinte din modalele de editare au hx-disabled-elt="find button"; atributul se MOSTENESTE pe butoanele chips, iar find button rezolvat relativ la butonul "+" (fara butoane descendente) → null → TypeError intern htmx 1.9.12 INAINTE de request → nicio cerere, nicio eroare vizibila. Fix: hx-disabled-elt="this" explicit pe toate butoanele hx-post din _chips_prestatii.html (care si dezactiveaza butonul cat cererea e in zbor). No-op-urile silentioase server-side (cod invalid pe add/add_flat, duplicat) erau defecte reale suplimentare, reparate separat.

Observatii non-blocante: (1) bulk_message ("N reusite") dispare imediat — HX-Trigger trimiteriChanged reincarca lista peste raspunsul cu mesaj (comportament pre-existent); (2) pe mobil, operatia e trunchiata agresiv pe randurile cu buton "Trimite" (spatiul e consumat de actiune + mediu + status) — acceptat, informatia completa e in modal.