feat(editor): editor prestatii unificat in modal - un select, un rand de chips (PRD 5.23)
Inlocuieste cele 3 controale de asociere cod RAR cu un singur rand de chips + un singur select care adauga instant la change. Stare = un hidden chips_state JSON versionat; post_form_chips redus la 2 actiuni (add/remove). Optgroup Sugestii (fuzzy/k-NN) + optiune "Nu se declara la RAR" in select, cu tinta implicita evidentiata si placeholder care o numeste. exclus persistat prin payload_json (treapta noua de precedenta in resolve_prestatii, round-trip complet). Siguranta: itemii exclusi sunt scosi din payload la momentul trimiterii (worker split_prestatii_excluse inainte de build_rar_payload + filtru defensiv), ca sa nu ajunga NICIODATA la RAR ca codPrestatie:null. Suita: 1680 passed, 1 skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,233 +1,175 @@
|
||||
{#
|
||||
_chips_prestatii.html — sectiunea de prestatii chips (E4, server-driven via /form-chips).
|
||||
_chips_prestatii.html — control unificat chips prestatii.
|
||||
|
||||
Re-randata de endpoint-ul /form-chips la fiecare add/remove de chip.
|
||||
Inclusa si din _form_editare.html pentru randarea initiala.
|
||||
UN singur container `.chips`: chips cod (legate de operatie sau libere), chips
|
||||
warning pentru operatii nemapate, chip `Nedeclarat` pentru itemi exclusi, si
|
||||
selectul unic `chips_pick` la final. Fara `.op-row`, fara butoane Adauga/+ —
|
||||
selectul adauga instant la `change` (POST /form-chips, chips_action=add).
|
||||
|
||||
Starea chip-urilor traieste in input-uri hidden din form (NU in DB mid-edit).
|
||||
Fiecare operatie are un picker propriu cand e nemapata (E4 binding op<->cod).
|
||||
Reveal odometru initial semnalat prin data-has-r-odo="true" si chip-warn pe R-ODO/I-ODO.
|
||||
Diagrama starii per item (chips_state.items[i]):
|
||||
cod="" & exclus=0 -> chip warning (warn OP-X . fara cod), click = tinta
|
||||
cod="" & exclus=1 -> chip Nedeclarat (line-through), x -> readuce warning
|
||||
cod!="" (op="" sau op!="") -> chip cod (eticheta COD, tooltip = operatia sursa
|
||||
sau "cod adaugat manual")
|
||||
|
||||
Stare persistata intr-UN SINGUR hidden `chips_state` (JSON versionat)
|
||||
+ hidden `chips_target_index` (tinta curenta; comutata CLIENT-SIDE la click pe
|
||||
un chip warning, fara round-trip — indexul pleaca la server abia la urmatorul
|
||||
add) + hidden `chips_submission_id` (ecouat ca sa "salveaza ca regula" ramana
|
||||
disponibil dupa re-randari via /form-chips).
|
||||
|
||||
Context vars (toate cu defaults):
|
||||
prestatii_chips — list of {cod_prestatie, cod_op_service, denumire}
|
||||
nomenclator_rar — list of {cod_prestatie, nume_prestatie} pentru picker
|
||||
has_r_odo — True daca orice chip e R-ODO sau I-ODO (server-computed)
|
||||
form_chips_url — URL pentru HTMX; default '/form-chips'
|
||||
chips_section_id — ID div (default 'chips-section')
|
||||
csrf_token — CSRF (trecut prin hx-include din form parinte)
|
||||
prestatii_chips — list of {cod_prestatie, cod_op_service, denumire, exclus}
|
||||
nomenclator_rar — list of {cod_prestatie, nume_prestatie} pentru select
|
||||
has_r_odo — True daca vreun chip e R-ODO/I-ODO (server-computed)
|
||||
chips_added_index — index-ul chip-ului tocmai adaugat (emfaza chip-nou)
|
||||
chips_target_index — index-ul operatiei tinta curente (sau none)
|
||||
chips_submission_id — id submission cand chips sunt in modalul de detaliu
|
||||
(activeaza butonul "salveaza ca regula")
|
||||
form_chips_url — URL pentru HTMX; default '/form-chips'
|
||||
chips_section_id — ID div (default 'chips-section')
|
||||
csrf_token — CSRF (trecut prin hx-include din form parinte)
|
||||
#}
|
||||
{% set _chips_url = form_chips_url or '/form-chips' %}
|
||||
{% set _sec_id = chips_section_id or 'chips-section' %}
|
||||
{% set _chips = prestatii_chips or [] %}
|
||||
{% set _has_ops = _chips | selectattr('cod_op_service') | list | length > 0 %}
|
||||
{# chips_submission_id e setat din _detaliu_ctx cand chips sunt randate in modalul de detaliu.
|
||||
Lipseste cand _chips_prestatii.html e rerandat via /form-chips (stateless, fara submission). #}
|
||||
{% set _sub_id = chips_submission_id if chips_submission_id is defined else none %}
|
||||
{% set _sub_id = chips_submission_id if (chips_submission_id is defined and chips_submission_id) else '' %}
|
||||
{% set _target_idx = chips_target_index if (chips_target_index is defined and chips_target_index is not none) else none %}
|
||||
{% set _target_op = (_chips[_target_idx].cod_op_service or '') if (_target_idx is not none and _target_idx < _chips | length) else '' %}
|
||||
|
||||
<div id="{{ _sec_id }}" data-has-r-odo="{{ 'true' if has_r_odo else 'false' }}"
|
||||
<div id="{{ _sec_id }}" class="chips-editor" data-has-r-odo="{{ 'true' if has_r_odo else 'false' }}"
|
||||
aria-live="polite" aria-label="Prestatii cod RAR">
|
||||
|
||||
{# ===== Input-uri hidden pentru starea curenta a chip-urilor =====
|
||||
TOATE itemele emit 3 hidden inputs (cod poate fi "" pentru unmapped).
|
||||
Paralele index-by-index: cod_prestatie[i], chip_op_service[i], chip_denumire[i].
|
||||
Filtrate la submit de post_corectie_trimitere (coduri goale = neschimbate). #}
|
||||
{% for chip in _chips %}
|
||||
<input type="hidden" name="cod_prestatie" value="{{ chip.cod_prestatie or '' }}">
|
||||
<input type="hidden" name="chip_op_service" value="{{ chip.cod_op_service or '' }}">
|
||||
<input type="hidden" name="chip_denumire" value="{{ chip.denumire or '' }}">
|
||||
{% endfor %}
|
||||
{# ===== Stare: UN SINGUR hidden JSON versionat + tinta + submission id ===== #}
|
||||
<input type="hidden" name="chips_state" value='{{ chips_state_json(_chips) }}'>
|
||||
<input type="hidden" name="chips_target_index" id="chips-target-index"
|
||||
value="{{ _target_idx if _target_idx is not none else '' }}">
|
||||
<input type="hidden" name="chips_submission_id" value="{{ _sub_id }}">
|
||||
|
||||
<div class="camp-slim" style="margin-bottom:8px;">
|
||||
<label>Prestatii — cod RAR pe fiecare operatie</label>
|
||||
<label>Prestatii — cod RAR</label>
|
||||
|
||||
{% if _has_ops %}
|
||||
{# ===== Mod operatii: UN picker PE operatie (E4 binding) ===== #}
|
||||
{% for chip in _chips %}
|
||||
{% if chip.cod_op_service %}
|
||||
{% set _is_warn = chip.cod_prestatie in ('R-ODO', 'I-ODO') %}
|
||||
{% set _nemapat = not chip.cod_prestatie %}
|
||||
{% set _e_nou = (chips_added_cod is defined) and chips_added_cod and chip.cod_prestatie == chips_added_cod %}
|
||||
<div class="op-row {% if _nemapat %}op-row-warn{% endif %}" style="margin-bottom:6px;">
|
||||
<span class="op-row-name">
|
||||
{{ chip.cod_op_service }}
|
||||
{% if chip.denumire and chip.denumire != chip.cod_op_service %}
|
||||
<span class="muted" style="font-weight:400;font-size:11px;"> — {{ chip.denumire }}</span>
|
||||
{% endif %}
|
||||
{% if _nemapat %}
|
||||
<span style="color:var(--warn);font-size:10px;font-weight:400;"> · lipsa cod</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
<span style="display:flex;align-items:center;gap:8px;">
|
||||
{% if chip.cod_prestatie %}
|
||||
{# ===== Operatie mapata: chip cu × ===== #}
|
||||
<span class="chip {% if _is_warn %}chip-warn{% endif %} {% if _e_nou %}chip-nou{% endif %}"
|
||||
aria-label="Prestatie {{ chip.cod_prestatie }} adaugata pentru {{ chip.cod_op_service }}">
|
||||
{{ chip.cod_prestatie }}
|
||||
<button type="button" class="chip-del"
|
||||
hx-post="{{ _chips_url }}"
|
||||
hx-disabled-elt="this"
|
||||
hx-include="closest form"
|
||||
hx-target="#{{ _sec_id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-vals='{"chips_action":"remove","chips_remove_index":{{ loop.index0 }}}'
|
||||
aria-label="Sterge codul {{ chip.cod_prestatie }} pentru {{ chip.cod_op_service }}">
|
||||
×
|
||||
</button>
|
||||
</span>
|
||||
{# "salveaza ca regula op->cod" — apare doar cand submission_id e cunoscut
|
||||
(in modalul de detaliu, nu la re-randarea stateless via /form-chips).
|
||||
Reuse EXACT save_mapping + reresolve_account via endpoint dedicat.
|
||||
hx-include="closest form" propaga csrf_token din form-ul parinte. #}
|
||||
<span id="save-rule-slot-{{ loop.index0 }}" class="save-rule-slot">
|
||||
{% if _sub_id and chip.cod_op_service and chip.cod_prestatie %}
|
||||
<button type="button"
|
||||
style="font-size:10px;color:var(--muted);background:none;border:none;cursor:pointer;text-decoration:underline;padding:0;margin-left:4px;line-height:1;"
|
||||
hx-post="/trimitere/{{ _sub_id }}/salveaza-regula-chip"
|
||||
hx-disabled-elt="this"
|
||||
hx-include="closest form"
|
||||
hx-target="#detaliu-modal-body"
|
||||
hx-swap="innerHTML"
|
||||
hx-vals='{"salveaza_op":{{ chip.cod_op_service | tojson }},"salveaza_cod":{{ chip.cod_prestatie | tojson }}}'
|
||||
aria-label="Salveaza regula {{ chip.cod_op_service }} -> {{ chip.cod_prestatie }}">
|
||||
salveaza ca regula
|
||||
</button>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% else %}
|
||||
{# ===== Operatie nemapata: picker galben cu "alege cod RAR" ===== #}
|
||||
<select name="chips_add_cod_{{ loop.index0 }}"
|
||||
id="picker-op-{{ loop.index0 }}"
|
||||
aria-label="Alege cod RAR pentru {{ chip.cod_op_service }}"
|
||||
style="min-width:160px;font-size:11px;height:26px;">
|
||||
<option value="">— alege cod RAR —</option>
|
||||
{% for n in (nomenclator_rar or []) %}
|
||||
<option value="{{ n.cod_prestatie }}">{{ n.cod_prestatie }} — {{ n.nume_prestatie }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="button"
|
||||
class="add-code"
|
||||
hx-post="{{ _chips_url }}"
|
||||
hx-disabled-elt="this"
|
||||
hx-include="closest form"
|
||||
hx-target="#{{ _sec_id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-vals='{"chips_action":"add","chips_add_op_index":{{ loop.index0 }}}'
|
||||
aria-label="Adauga cod RAR pentru {{ chip.cod_op_service }}">
|
||||
+ Adauga
|
||||
</button>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<div class="chips" role="group" aria-label="Prestatii cod RAR">
|
||||
{% for chip in _chips %}
|
||||
{% set _idx = loop.index0 %}
|
||||
{% set _is_target = _target_idx is not none and _idx == _target_idx %}
|
||||
|
||||
{# ===== Chips extra + picker '+ Adauga alta operatie / cod RAR' in mod operatii ===== #}
|
||||
{# Chips extra: cod_op_service gol, cod_prestatie setat — afisate flat cu × (reuse remove_flat).
|
||||
Containerul .chips se randeaza DOAR cand exista chips extra — altfel ramanea
|
||||
un chenar gol nefinisat sub randurile de operatie. #}
|
||||
{% set _extra_chips = _chips | rejectattr('cod_op_service') | selectattr('cod_prestatie') | list %}
|
||||
{% if _extra_chips %}
|
||||
<div class="chips" role="group" aria-label="Coduri RAR suplimentare" style="margin-top:4px;">
|
||||
{% for chip in _extra_chips %}
|
||||
{% set _is_warn_extra = chip.cod_prestatie in ('R-ODO', 'I-ODO') %}
|
||||
{% set _e_nou_extra = (chips_added_cod is defined) and chips_added_cod and chip.cod_prestatie == chips_added_cod %}
|
||||
<span class="chip {% if _is_warn_extra %}chip-warn{% endif %} {% if _e_nou_extra %}chip-nou{% endif %}"
|
||||
aria-label="Cod RAR suplimentar {{ chip.cod_prestatie }}">
|
||||
{{ chip.cod_prestatie }}
|
||||
{% if chip.cod_op_service and not chip.cod_prestatie and not chip.exclus %}
|
||||
{# ===== Chip warning: operatie nemapata — click comuta tinta client-side ===== #}
|
||||
{% set _label = chip.cod_op_service %}
|
||||
{% set _label_scurt = (_label[:18] ~ '…') if _label | length > 18 else _label %}
|
||||
{% set _title = chip.cod_op_service ~ (' — ' ~ chip.denumire if chip.denumire and chip.denumire != chip.cod_op_service else '') %}
|
||||
<button type="button"
|
||||
class="chip chip-op-warn {% if _is_target %}is-target{% endif %}"
|
||||
data-chip-idx="{{ _idx }}"
|
||||
data-op-nume="{{ chip.cod_op_service }}"
|
||||
title="{{ _title }}"
|
||||
onclick="window.chipsSetTarget && window.chipsSetTarget(this, {{ _idx }})"
|
||||
aria-pressed="{{ 'true' if _is_target else 'false' }}"
|
||||
aria-label="Operatia {{ chip.cod_op_service }} nu are cod RAR{% if _is_target %} (tinta curenta){% endif %}">
|
||||
⚠ {{ _label_scurt }} · fara cod
|
||||
</button>
|
||||
|
||||
{% elif chip.exclus %}
|
||||
{# ===== Chip Nedeclarat: vizibil (line-through), x readuce warning-ul ===== #}
|
||||
<span class="chip chip-nedeclarat"
|
||||
title="{{ chip.cod_op_service or 'Cod liber' }} — nu se declara la RAR"
|
||||
aria-label="{{ chip.cod_op_service or 'Operatia' }} nu se declara la RAR">
|
||||
Nedeclarat
|
||||
<button type="button" class="chip-del"
|
||||
hx-post="{{ _chips_url }}"
|
||||
hx-disabled-elt="this"
|
||||
hx-indicator="#{{ _sec_id }}"
|
||||
hx-include="closest form"
|
||||
hx-target="#{{ _sec_id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-vals='{"chips_action":"remove_flat","chips_remove_cod":"{{ chip.cod_prestatie }}"}'
|
||||
aria-label="Sterge codul suplimentar {{ chip.cod_prestatie }}">×</button>
|
||||
hx-vals='{"chips_action":"remove","chips_remove_index":{{ _idx }}}'
|
||||
aria-label="Anuleaza Nedeclarat pentru {{ chip.cod_op_service or 'cod liber' }} (readuce avertismentul)">
|
||||
×
|
||||
</button>
|
||||
</span>
|
||||
|
||||
{% elif chip.cod_prestatie %}
|
||||
{# ===== Chip cod: legat de operatie sau liber ===== #}
|
||||
{% set _is_warn = chip.cod_prestatie in ('R-ODO', 'I-ODO') %}
|
||||
{% set _e_nou = (chips_added_index is defined) and chips_added_index is not none and _idx == chips_added_index %}
|
||||
{% set _tooltip = (chip.cod_op_service ~ (' — ' ~ chip.denumire if chip.denumire and chip.denumire != chip.cod_op_service else '')) if chip.cod_op_service else 'cod adaugat manual' %}
|
||||
<span class="chip {% if _is_warn %}chip-warn{% endif %} {% if _e_nou %}chip-nou{% endif %}"
|
||||
title="{{ _tooltip }}"
|
||||
aria-label="Prestatie {{ chip.cod_prestatie }}{% if chip.cod_op_service %} pentru {{ chip.cod_op_service }}{% endif %}">
|
||||
<span class="chip-cod-label">COD</span> {{ chip.cod_prestatie }}
|
||||
<button type="button" class="chip-del"
|
||||
hx-post="{{ _chips_url }}"
|
||||
hx-disabled-elt="this"
|
||||
hx-indicator="#{{ _sec_id }}"
|
||||
hx-include="closest form"
|
||||
hx-target="#{{ _sec_id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-vals='{"chips_action":"remove","chips_remove_index":{{ _idx }}}'
|
||||
aria-label="Sterge codul {{ chip.cod_prestatie }}{% if chip.cod_op_service %} pentru {{ chip.cod_op_service }}{% endif %}">
|
||||
×
|
||||
</button>
|
||||
</span>
|
||||
{# "salveaza ca regula op->cod" — apare doar cand submission_id e cunoscut
|
||||
(modalul de detaliu, nu la re-randarea stateless via /form-chips fara ecou). #}
|
||||
{% if _sub_id and chip.cod_op_service and chip.cod_prestatie %}
|
||||
<span id="save-rule-slot-{{ _idx }}" class="save-rule-slot">
|
||||
<button type="button"
|
||||
style="font-size:10px;color:var(--muted);background:none;border:none;cursor:pointer;text-decoration:underline;padding:0;margin-left:-2px;line-height:1;"
|
||||
hx-post="/trimitere/{{ _sub_id }}/salveaza-regula-chip"
|
||||
hx-disabled-elt="this"
|
||||
hx-indicator="#{{ _sec_id }}"
|
||||
hx-include="closest form"
|
||||
hx-target="#detaliu-modal-body"
|
||||
hx-swap="innerHTML"
|
||||
hx-vals='{"salveaza_op":{{ chip.cod_op_service | tojson }},"salveaza_cod":{{ chip.cod_prestatie | tojson }}}'
|
||||
aria-label="Salveaza regula {{ chip.cod_op_service }} -> {{ chip.cod_prestatie }}">
|
||||
salveaza ca regula
|
||||
</button>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if nomenclator_rar %}
|
||||
<span style="display:inline-flex;align-items:center;gap:4px;margin-top:4px;">
|
||||
<select name="chips_add_cod_flat"
|
||||
aria-label="Adauga cod RAR suplimentar"
|
||||
style="min-width:160px;font-size:11px;height:26px;border:1px dashed color-mix(in srgb,var(--accent) 55%,var(--line));border-radius:5px;background:transparent;color:var(--accent);">
|
||||
<option value="">+ Adauga alta operatie / cod RAR</option>
|
||||
{% for n in nomenclator_rar %}
|
||||
|
||||
{# ===== Selectul unic: adauga instant la schimbare, placeholder numeste tinta ===== #}
|
||||
{% if nomenclator_rar %}
|
||||
<select name="chips_pick"
|
||||
id="chips-picker"
|
||||
class="chips-picker"
|
||||
hx-trigger="change"
|
||||
hx-post="{{ _chips_url }}"
|
||||
hx-target="#{{ _sec_id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-include="closest form"
|
||||
hx-disabled-elt="this"
|
||||
hx-indicator="#{{ _sec_id }}"
|
||||
hx-vals='{"chips_action":"add"}'
|
||||
aria-label="{% if _target_op %}Alege cod RAR pentru {{ _target_op }}{% else %}Adauga cod RAR{% endif %}">
|
||||
<option value="">{% if _target_op %}Cod pentru {{ _target_op }} — alege{% else %}— adauga cod RAR —{% endif %}</option>
|
||||
{% if _target_idx is not none %}
|
||||
{% set _sugestii = sugestii_tinta if (sugestii_tinta is defined and sugestii_tinta) else [] %}
|
||||
{% if _sugestii %}
|
||||
<optgroup label="Sugestii">
|
||||
{% for s in _sugestii %}
|
||||
<option value="{{ s.cod_prestatie }}">{{ s.cod_prestatie }} — {{ s.nume_prestatie }}</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
{% endif %}
|
||||
<option value="{{ EXCLUDE_SENTINEL }}">Nu se declara la RAR (exclude operatia)</option>
|
||||
{% endif %}
|
||||
{% for n in (nomenclator_rar or []) %}
|
||||
<option value="{{ n.cod_prestatie }}">{{ n.cod_prestatie }} — {{ n.nume_prestatie }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="button"
|
||||
class="add-code"
|
||||
hx-post="{{ _chips_url }}"
|
||||
hx-disabled-elt="this"
|
||||
hx-include="closest form"
|
||||
hx-target="#{{ _sec_id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-vals='{"chips_action":"add_extra"}'
|
||||
aria-label="Adauga cod RAR suplimentar la trimitere">
|
||||
+
|
||||
</button>
|
||||
</span>
|
||||
{% else %}
|
||||
{# T-D1/T-E5 (5.16): empty state in mod operatii cand nomenclatorul lipseste #}
|
||||
<div class="chips-nom-gol" style="font-size:11px;color:var(--warn);padding:4px 0;margin-top:4px;">
|
||||
Nomenclator indisponibil — adaugarea de coduri suplimentare nu e posibila.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{# ===== Mod plat: lista de coduri libere (corectie pura, fara op_service) ===== #}
|
||||
<div class="chips" role="group" aria-label="Coduri RAR selectate">
|
||||
{% for chip in _chips %}
|
||||
{% if chip.cod_prestatie %}
|
||||
{% set _is_warn_flat = chip.cod_prestatie in ('R-ODO', 'I-ODO') %}
|
||||
{% set _e_nou_flat = (chips_added_cod is defined) and chips_added_cod and chip.cod_prestatie == chips_added_cod %}
|
||||
<span class="chip {% if _is_warn_flat %}chip-warn{% endif %} {% if _e_nou_flat %}chip-nou{% endif %}"
|
||||
aria-label="Prestatie {{ chip.cod_prestatie }}">
|
||||
{{ chip.cod_prestatie }}
|
||||
<button type="button" class="chip-del"
|
||||
hx-post="{{ _chips_url }}"
|
||||
hx-disabled-elt="this"
|
||||
hx-include="closest form"
|
||||
hx-target="#{{ _sec_id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-vals='{"chips_action":"remove_flat","chips_remove_cod":"{{ chip.cod_prestatie }}"}'
|
||||
aria-label="Sterge codul {{ chip.cod_prestatie }}">×</button>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{# Picker adaugare cod nou in mod plat #}
|
||||
{% if nomenclator_rar %}
|
||||
<span style="display:inline-flex;align-items:center;gap:4px;">
|
||||
<select name="chips_add_cod_flat"
|
||||
aria-label="Adauga cod RAR nou"
|
||||
style="font-size:11px;height:22px;border:1px dashed color-mix(in srgb,var(--accent) 55%,var(--line));border-radius:5px;background:transparent;color:var(--accent);">
|
||||
<option value="">+ cod</option>
|
||||
{% for n in nomenclator_rar %}
|
||||
<option value="{{ n.cod_prestatie }}">{{ n.cod_prestatie }} — {{ n.nume_prestatie }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="button"
|
||||
class="add-code"
|
||||
hx-post="{{ _chips_url }}"
|
||||
hx-disabled-elt="this"
|
||||
hx-include="closest form"
|
||||
hx-target="#{{ _sec_id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-vals='{"chips_action":"add_flat"}'
|
||||
aria-label="Adauga cod RAR selectat in lista">
|
||||
+
|
||||
</button>
|
||||
</span>
|
||||
{% else %}
|
||||
{# T-D1/T-E5 (5.16): empty state in mod plat cand nomenclatorul lipseste #}
|
||||
{# T-D1/T-E5 (5.16): empty state cand nomenclatorul lipseste #}
|
||||
<div class="chips-nom-gol" style="font-size:11px;color:var(--warn);padding:4px 0;">
|
||||
Nomenclator indisponibil — nu se pot adauga coduri RAR momentan.
|
||||
Nomenclator indisponibil — adaugarea de coduri RAR nu e posibila.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Rezultatul ultimei adaugari, in ambele moduri: refuz (rol=alert) sau confirmare.
|
||||
{# Rezultatul ultimei adaugari: refuz (rol=alert) sau confirmare.
|
||||
Clasa chips-extra-error pastrata pe eroare (selector stabil pentru teste/QA). #}
|
||||
{% if chips_error is defined and chips_error %}
|
||||
<div class="chips-extra-error" style="font-size:11px;color:var(--err);padding:2px 0;" role="alert">
|
||||
@@ -238,12 +180,40 @@
|
||||
{{ chips_ok }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Hint discret fara chips (debut) #}
|
||||
{% if not _chips %}
|
||||
<div style="font-size:10px;color:var(--muted);padding:4px 0;">
|
||||
Niciun cod RAR inca — alege din picker (sus) sau adauga prin mapare.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
if (window.__chipsUnifiedBound) { return; }
|
||||
window.__chipsUnifiedBound = true;
|
||||
|
||||
// Click pe chip warning -> comuta tinta CLIENT-SIDE (fara round-trip). Click
|
||||
// pe tinta activa = no-op (nu se poate "deselecta" tinta cat exista warnings).
|
||||
window.chipsSetTarget = function (btn, idx) {
|
||||
var hidden = document.getElementById('chips-target-index');
|
||||
if (!hidden) { return; }
|
||||
if (String(idx) === hidden.value) { return; }
|
||||
hidden.value = String(idx);
|
||||
document.querySelectorAll('.chip-op-warn.is-target').forEach(function (el) {
|
||||
el.classList.remove('is-target');
|
||||
el.setAttribute('aria-pressed', 'false');
|
||||
});
|
||||
btn.classList.add('is-target');
|
||||
btn.setAttribute('aria-pressed', 'true');
|
||||
var picker = document.getElementById('chips-picker');
|
||||
if (picker && picker.options.length) {
|
||||
picker.options[0].textContent = 'Cod pentru ' + (btn.dataset.opNume || '') + ' — alege';
|
||||
}
|
||||
};
|
||||
|
||||
// Focus restaurat pe select dupa fiecare swap outerHTML al sectiunii.
|
||||
document.body.addEventListener('htmx:afterSettle', function (evt) {
|
||||
var t = evt.target;
|
||||
if (t && t.classList && t.classList.contains('chips-editor')) {
|
||||
var el = document.getElementById('chips-picker');
|
||||
if (el) { el.focus(); }
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
@@ -828,19 +828,22 @@
|
||||
.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));
|
||||
border-radius:5px; color:var(--accent); font:500 10px var(--font-ui); cursor:pointer; }
|
||||
.add-code:hover, .add-code:focus-visible { border-style:solid; }
|
||||
/* .op-row — rand operatie cu picker op<->cod (E4): operatie + chip cod + picker */
|
||||
.op-row { display:flex; align-items:center; justify-content:space-between; gap:10px;
|
||||
padding:8px 10px; border:1px solid var(--line); border-radius:6px;
|
||||
background:var(--card2); margin-bottom:8px; }
|
||||
/* Nume operatie emfatic (T-9 5.16): proeminent (bold) ca in mockup — e ancora
|
||||
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)); }
|
||||
/* Eticheta mono "COD" pe chip-ul de cod */
|
||||
.chip-cod-label { font-size:9px; font-weight:800; opacity:.65; letter-spacing:.03em; }
|
||||
/* Chip warning operatie nemapata: dashed implicit; tinta activa = solid + inel —
|
||||
singurul tratament "tare" din rand. */
|
||||
.chip-op-warn { background:color-mix(in srgb, var(--warn) 16%, transparent); color:var(--warn);
|
||||
border:1px dashed var(--warn); cursor:pointer; font-weight:600; }
|
||||
.chip-op-warn.is-target { border-style:solid; outline:2px solid color-mix(in srgb, var(--warn) 40%, transparent);
|
||||
outline-offset:1px; }
|
||||
.chip-op-warn:focus-visible { outline:2px solid var(--warn); outline-offset:1px; }
|
||||
/* Chip Nedeclarat: vizibil (line-through), NU mut/invizibil — cea mai riscanta
|
||||
actiune legala (exclude de la declararea RAR) nu poate fi cea mai discreta. */
|
||||
.chip-nedeclarat { background:var(--card2); color:var(--muted); border:1px dashed var(--line);
|
||||
text-decoration:line-through; }
|
||||
/* Sectiunea chips inerta pe durata unui request /form-chips in zbor:
|
||||
click pe x/warning mid-flight nu se pierde, doar se ignora. */
|
||||
.chips-editor.htmx-request { pointer-events:none; opacity:.7; }
|
||||
/* 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 "·". */
|
||||
|
||||
Reference in New Issue
Block a user