feat(2.0): remove a coluna de variáveis — vira autocomplete no campo de valor

Feedback de UX: com o Gerar template automático, a coluna ficava ociosa.
As variáveis do GLPI agora aparecem como autocomplete (datalist) direto no
campo de valor de cada linha, + um painel de referência colapsado (fechado
por padrão) para descoberta em remapeamentos. Editores em largura total.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Gemini 2026-07-02 17:12:32 -03:00
parent 48600b9692
commit 5ee12c75d2

View file

@ -153,32 +153,36 @@
{{ __('Personalize o JSON enviado ao Redmine em cada operação. Sem template ativo, o plugin usa o comportamento padrão. "Gerar template" cria o ponto de partida equivalente ao padrão + campos obrigatórios descobertos no seu Redmine.', 'redmine') }} {{ __('Personalize o JSON enviado ao Redmine em cada operação. Sem template ativo, o plugin usa o comportamento padrão. "Gerar template" cria o ponto de partida equivalente ao padrão + campos obrigatórios descobertos no seu Redmine.', 'redmine') }}
</div> </div>
<div class="row"> {# Variáveis do GLPI como AUTOCOMPLETE nos campos de valor #}
{# ---- Paleta ---- #} <datalist id="rm-glpi-vars">
<div class="col-lg-4"> {% for v in palette_vars %}
<div class="card"> <option value="{{ v.tag }}">{{ v.group }}{{ v.desc }}</option>
<div class="card-header py-2"> {% endfor %}
<strong>{{ __('Variáveis do GLPI — o "DE"', 'redmine') }}</strong> </datalist>
<div class="text-muted" style="font-size:.7rem">{{ __('Clique para copiar a tag. Os campos que o Redmine espera (o "PARA") estão em cada operação, à direita.', 'redmine') }}</div>
</div> {# Referência opcional (colapsada) — descoberta das tags para remapeamentos #}
<div class="card-body p-2" style="max-height: 480px; overflow-y: auto;"> <div class="mb-3">
<a class="small" data-bs-toggle="collapse" href="#rm-glpi-vars-panel" role="button">
<i class="ti ti-variable me-1"></i>{{ __('Variáveis do GLPI disponíveis — o "DE" (referência; nos campos de valor há autocomplete)', 'redmine') }}
</a>
<div class="collapse" id="rm-glpi-vars-panel">
<div class="card card-body p-2 mt-1" style="max-height:300px;overflow-y:auto;columns:2">
{% set lastgroup = '' %} {% set lastgroup = '' %}
{% for v in palette_vars %} {% for v in palette_vars %}
{% if v.group != lastgroup %} {% if v.group != lastgroup %}
{% set lastgroup = v.group %} {% set lastgroup = v.group %}
<div class="mt-2 mb-1 text-uppercase text-muted" style="font-size: .7rem;">{{ v.group }}</div> <div class="mt-1 mb-1 text-uppercase text-muted" style="font-size:.7rem;break-inside:avoid">{{ v.group }}</div>
{% endif %} {% endif %}
<div class="rm-var d-flex justify-content-between align-items-center px-1 rounded" data-tag="{{ v.tag }}" title="{{ v.desc }}"> <div class="rm-var px-1 rounded" data-tag="{{ v.tag }}" title="{{ v.desc }}" style="break-inside:avoid">
<code style="font-size:.75rem">{{ v.tag }}</code> <code style="font-size:.75rem">{{ v.tag }}</code>
<i class="ti ti-copy text-muted" style="font-size:.7rem"></i>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
</div> </div>
{# ---- Editores por operação ---- #} {# ---- Editores por operação (largura total) ---- #}
<div class="col-lg-8"> <div>
{% for op, t in templates %} {% for op, t in templates %}
<form method="post" action="{{ action_url }}"> <form method="post" action="{{ action_url }}">
<input type="hidden" name="_glpi_csrf_token" value="{{ csrf_token_value }}"> <input type="hidden" name="_glpi_csrf_token" value="{{ csrf_token_value }}">
@ -251,7 +255,6 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
</div>
</div> </div>
{% verbatim %} {% verbatim %}
@ -330,7 +333,7 @@
row.className = 'd-flex gap-2 mb-1 rm-tpl-row'; row.className = 'd-flex gap-2 mb-1 rm-tpl-row';
row.innerHTML = row.innerHTML =
'<input class="form-control form-control-sm rm-k" style="max-width:42%;font-family:monospace;font-size:.78rem" placeholder="caminho.do.campo" value="' + esc(p) + '">' + '<input class="form-control form-control-sm rm-k" style="max-width:42%;font-family:monospace;font-size:.78rem" placeholder="caminho.do.campo" value="' + esc(p) + '">' +
'<input class="form-control form-control-sm rm-v" style="font-family:monospace;font-size:.78rem" placeholder="valor fixo ou tag da paleta" value="' + esc(v) + '">' + '<input class="form-control form-control-sm rm-v" list="rm-glpi-vars" style="font-family:monospace;font-size:.78rem" placeholder="valor fixo ou variável do GLPI (autocomplete)" value="' + esc(v) + '">' +
'<button type="button" class="btn btn-sm btn-outline-danger rm-del">&times;</button>'; '<button type="button" class="btn btn-sm btn-outline-danger rm-del">&times;</button>';
row.querySelector('.rm-del').addEventListener('click', function () { row.remove(); }); row.querySelector('.rm-del').addEventListener('click', function () { row.remove(); });
linesBox.appendChild(row); linesBox.appendChild(row);