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>
This commit is contained in:
@@ -741,35 +741,68 @@
|
||||
.compact-nr { font-size:var(--fs-xl); font-weight:700; line-height:1; }
|
||||
.compact-lbl { font-size:10px; color:var(--muted); margin-top:3px; white-space:nowrap; }
|
||||
}
|
||||
/* .lista-trimiteri-slim + .trimitere-slim — lista compacta cu separator --line2.
|
||||
Randul e clickabil (rol button), tinta min-height:44px pe mobil. */
|
||||
/* Bara contextuala bulk (5.22): ascunsa fara selectie; .activ (setat de JS
|
||||
cand >=1 checkbox e bifat) o afiseaza impreuna cu hint-ul de sub ea. */
|
||||
.bulk-bar { display:none; align-items:center; gap:8px; flex-wrap:wrap; font-size:13px;
|
||||
background:color-mix(in srgb, var(--accent) 10%, var(--card));
|
||||
border:1px solid color-mix(in srgb, var(--accent) 40%, transparent);
|
||||
border-radius:8px; padding:8px 12px; margin-bottom:4px; }
|
||||
.bulk-bar.activ { display:flex; }
|
||||
.bulk-hint { display:none; font-size:12px; color:var(--muted); margin:0 0 8px; }
|
||||
.bulk-bar.activ + .bulk-hint { display:block; }
|
||||
|
||||
/* Tabel compact trimiteri (grid CSS, 5.22).
|
||||
Desktop: header de coloane + un rand per trimitere; sub-linia de eroare
|
||||
(.c-err) ocupa coloanele 2..-1 pe un al doilea rand de grid.
|
||||
Mobil (max-width:767px, mai jos): header ascuns, rand pe 2 linii. */
|
||||
.lista-trimiteri-slim { list-style:none; margin:0; padding:0; }
|
||||
.trimitere-slim { display:flex; align-items:center; justify-content:space-between; gap:12px;
|
||||
padding:14px 16px; border-bottom:1px solid var(--line2); min-height:44px; cursor:pointer; }
|
||||
.trimiteri-head, .trimitere-slim {
|
||||
display:grid; align-items:center; column-gap:10px; row-gap:2px;
|
||||
grid-template-columns:22px minmax(90px,150px) minmax(64px,auto) minmax(0,1fr) auto 46px 44px 84px; }
|
||||
.trimiteri-head { padding:2px 16px 8px; border-bottom:1px solid var(--line);
|
||||
font-size:10.5px; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
|
||||
color:var(--muted); }
|
||||
.trimiteri-head .th-c { text-align:center; }
|
||||
.trimitere-slim { padding:9px 16px; border-bottom:1px solid var(--line2);
|
||||
min-height:44px; cursor:pointer; }
|
||||
.trimitere-slim:last-child { border-bottom:none; }
|
||||
.trimitere-slim:hover { background:color-mix(in srgb, var(--accent) 6%, transparent); }
|
||||
.trimitere-slim:focus, .trimitere-slim:focus-visible { outline:2px solid var(--accent); outline-offset:-2px; }
|
||||
.slim-vin { font-family:var(--font-mono); font-size:var(--fs-md); font-weight:600; color:var(--ink); }
|
||||
.slim-meta { font-size:var(--fs-sm); color:var(--muted); margin-top:3px; }
|
||||
/* Linia 2 a randului slim (5.16): cod RAR · operatie (ellipsis) · data, pe UN rand.
|
||||
Ellipsis-ul pe operatie garanteaza 2 linii MAX si la 390px. */
|
||||
.slim-rand2 { display:flex; align-items:baseline; gap:6px; min-width:0; }
|
||||
.slim-rand2 .cod-rar-cod { flex:0 0 auto; font-family:var(--font-mono); font-weight:600;
|
||||
color:var(--accent); }
|
||||
.slim-rand2 .cod-rar-cod.muted { color:var(--muted); font-weight:500; }
|
||||
.slim-rand2 .slim-op { flex:1 1 auto; min-width:0; white-space:nowrap; overflow:hidden;
|
||||
text-overflow:ellipsis; color:var(--ink); }
|
||||
.slim-rand2 .slim-data { flex:0 0 auto; }
|
||||
.slim-rand2 .slim-op::before, .slim-rand2 .slim-data::before {
|
||||
content:"·"; color:var(--muted); margin-right:6px; }
|
||||
.lista-trimiteri-slim .eticheta-problema { font-size:var(--fs-xs); line-height:1.3; margin-top:2px; }
|
||||
/* Pill slim (5.16): fill-tint + dot 7px + text colorat per stare (currentColor din .s-*).
|
||||
Pastrat pe FIECARE rand inclusiv Finalizat (linistit dar prezent). */
|
||||
.lista-trimiteri-slim .pill { display:inline-flex; align-items:center; gap:5px; font-weight:600;
|
||||
background:color-mix(in srgb, currentColor 14%, transparent);
|
||||
border-color:color-mix(in srgb, currentColor 35%, transparent); }
|
||||
.lista-trimiteri-slim .pill::before { content:""; width:7px; height:7px; border-radius:99px;
|
||||
background:currentColor; flex-shrink:0; }
|
||||
.trimitere-slim .c-check { display:flex; align-items:center; }
|
||||
.slim-vin { font-family:var(--font-mono); font-size:var(--fs-sm); font-weight:600; color:var(--ink);
|
||||
white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
|
||||
/* Pe desktop copiii .c-meta devin celule de grid (cod / operatie / data). */
|
||||
.trimitere-slim .c-meta { display:contents; }
|
||||
.trimitere-slim .c-cod { white-space:nowrap; }
|
||||
.trimitere-slim .cod-rar-cod { font-family:var(--font-mono); font-weight:600;
|
||||
font-size:var(--fs-xs); color:var(--accent); }
|
||||
.trimitere-slim .cod-rar-cod.muted { color:var(--muted); font-weight:500; font-style:italic; }
|
||||
/* Badge +N: trimiterea are mai multe coduri RAR; toate stau in title. */
|
||||
.trimitere-slim .cod-plus { display:inline-block; font-family:var(--font-mono);
|
||||
font-size:10px; font-weight:700; color:var(--muted); border:1px solid var(--line);
|
||||
border-radius:99px; padding:0 5px; margin-left:4px; vertical-align:1px; cursor:default; }
|
||||
.trimitere-slim .c-op { min-width:0; white-space:nowrap; overflow:hidden;
|
||||
text-overflow:ellipsis; font-size:var(--fs-sm); color:var(--ink); }
|
||||
.trimitere-slim .c-data { font-size:var(--fs-xs); color:var(--muted); white-space:nowrap;
|
||||
font-variant-numeric:tabular-nums; }
|
||||
.trimitere-slim .c-status, .trimitere-slim .c-env { justify-self:center; line-height:1;
|
||||
display:inline-flex; align-items:center; }
|
||||
/* Bulina de status: doar cerc colorat (currentColor din .s-*); numele starii
|
||||
traieste in headerul coloanei + title/aria-label. */
|
||||
.dot-stare { display:inline-block; width:11px; height:11px; border-radius:99px;
|
||||
background:currentColor; }
|
||||
/* Litera de mediu: P = fill atentie (declaratie reala, ireversibila — L.142);
|
||||
T = contur discret (mediu de proba). */
|
||||
.env-l { display:inline-flex; align-items:center; justify-content:center;
|
||||
width:20px; height:20px; border-radius:99px; font-size:11px; font-weight:800;
|
||||
cursor:default; }
|
||||
.env-l-prod { background:color-mix(in srgb, var(--err) 80%, var(--card)); color:var(--card); }
|
||||
.env-l-test { color:var(--muted); border:1px solid var(--line); }
|
||||
.trimitere-slim .c-act { justify-self:end; }
|
||||
/* Sub-linia de eroare: text brut, mono, un singur rand cu ellipsis (title = complet). */
|
||||
.trimitere-slim .c-err { grid-column:2 / -1; min-width:0; font-family:var(--font-mono);
|
||||
font-size:var(--fs-xs); color:var(--err); white-space:nowrap; overflow:hidden;
|
||||
text-overflow:ellipsis; }
|
||||
/* .camp-slim — varianta compacta camp formular: label --fs-sm muted deasupra, input --fs-md, fundal --card2.
|
||||
Mono pentru campuri VIN/odometru/nr: adauga clasa .camp-mono pe input. */
|
||||
.camp-slim { margin-bottom:8px; }
|
||||
@@ -793,6 +826,8 @@
|
||||
.chip .chip-del:focus-visible { outline:2px solid var(--accent); outline-offset:1px; }
|
||||
/* Varianta chip warn (ex. R-ODO necesita odometruInitial) */
|
||||
.chip-warn { background:color-mix(in srgb, var(--warn) 22%, transparent); color:var(--warn); }
|
||||
/* Chip abia adaugat via /form-chips — confirmare vizibila a actiunii "+" */
|
||||
.chip-nou { outline:2px solid color-mix(in srgb, var(--ok) 45%, transparent); outline-offset:1px; }
|
||||
/* .add-code — buton dashed pentru adaugare cod in chipbox */
|
||||
.add-code { display:inline-flex; align-items:center; height:22px; padding:0 7px; background:transparent;
|
||||
border:1px dashed color-mix(in srgb, var(--accent) 55%, var(--line));
|
||||
@@ -806,9 +841,30 @@
|
||||
vizuala a randului de mapare op<->cod. */
|
||||
.op-row-name { font-size:var(--fs-sm); font-weight:700; color:var(--ink); }
|
||||
.op-row-warn { border-color:color-mix(in srgb, var(--warn) 45%, var(--line)); }
|
||||
/* Mobil: tinta touch pentru trimitere-slim (deja garantata prin min-height:44px in regula de baza) */
|
||||
/* Mobil: fara header, randul revine la 2 linii (placuta / cod·operatie·data),
|
||||
cu actiune + litera mediu + bulina status in dreapta. Grid-areas peste
|
||||
aceleasi celule; .c-meta redevine linie flex cu separatoare "·". */
|
||||
@media (max-width:767px) {
|
||||
.trimitere-slim { padding:12px 14px; }
|
||||
.trimiteri-head { display:none; }
|
||||
.trimitere-slim { padding:12px 14px; column-gap:8px;
|
||||
grid-template-columns:22px minmax(0,1fr) auto auto auto;
|
||||
grid-template-areas:
|
||||
"check veh act env status"
|
||||
"check meta act env status"
|
||||
"err err err err err"; }
|
||||
.trimitere-slim .c-check { grid-area:check; }
|
||||
.trimitere-slim .slim-vin { grid-area:veh; font-size:var(--fs-md); }
|
||||
.trimitere-slim .c-meta { grid-area:meta; display:flex; align-items:baseline;
|
||||
gap:6px; min-width:0; margin-top:3px; }
|
||||
.trimitere-slim .c-cod { flex:0 0 auto; }
|
||||
.trimitere-slim .c-op { flex:1 1 auto; }
|
||||
.trimitere-slim .c-data { flex:0 0 auto; }
|
||||
.trimitere-slim .c-op::before, .trimitere-slim .c-data:not(:empty)::before {
|
||||
content:"·"; color:var(--muted); margin-right:6px; }
|
||||
.trimitere-slim .c-status { grid-area:status; }
|
||||
.trimitere-slim .c-env { grid-area:env; }
|
||||
.trimitere-slim .c-act { grid-area:act; }
|
||||
.trimitere-slim .c-err { grid-area:err; }
|
||||
}
|
||||
/* === SENTINEL-COMPONENTE-SLIM: sfarsit componente slim === */
|
||||
/* === Fix mobil Mapari ===
|
||||
@@ -1222,6 +1278,34 @@
|
||||
if (saveBtn) saveBtn.classList.add('dirty');
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// Bara contextuala bulk (trimiteri): vizibila DOAR cu selectie.
|
||||
// Delegare pe document (supravietuieste swap-urilor HTMX); dupa un swap al
|
||||
// listei checkbox-urile se reseteaza, deci sync() ascunde bara automat.
|
||||
(function() {
|
||||
function syncBulkBar() {
|
||||
var form = document.getElementById('bulk-trimiteri');
|
||||
var bar = document.getElementById('bulk-bar');
|
||||
if (!form || !bar) return;
|
||||
var n = form.querySelectorAll('input[name="submission_id"]:checked').length;
|
||||
bar.classList.toggle('activ', n > 0);
|
||||
bar.querySelectorAll('.bulk-n').forEach(function(el) { el.textContent = n; });
|
||||
bar.querySelectorAll('.bulk-n-txt').forEach(function(el) {
|
||||
el.textContent = (n === 1 ? 'rand' : 'randuri');
|
||||
});
|
||||
}
|
||||
document.addEventListener('change', function(e) {
|
||||
if (e.target && e.target.name === 'submission_id') syncBulkBar();
|
||||
});
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!(e.target.closest && e.target.closest('#bulk-deselect'))) return;
|
||||
document.querySelectorAll('#bulk-trimiteri input[name="submission_id"]:checked')
|
||||
.forEach(function(cb) { cb.checked = false; });
|
||||
syncBulkBar();
|
||||
});
|
||||
document.body.addEventListener('htmx:afterSwap', syncBulkBar);
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
// Sub-taburi pagina Setari: comutare pur client-side, fara server.
|
||||
// Delegare pe document -> supravietuieste swap-urilor HTMX ale #card-cont (dupa
|
||||
|
||||
Reference in New Issue
Block a user