, correção para gerara prévia do romaneio

This commit is contained in:
2026-08-28 12:00:53 -03:00
parent 94b2e5a0a5
commit b690dfb54c
6 changed files with 149 additions and 112 deletions

View File

@@ -1,12 +1,7 @@
<%# app/views/admin/romaneios/show.html.erb
Editor do romaneio: veículos à esquerda, tabela editável à direita, e o PDF
REAL numa sobreposição aberta sob demanda.
A prévia é um <iframe> de mesma origem, e isso não é preferência: o CSP deste
app está em modo enforcing com `object_src :none` (config/initializers/
content_security_policy.rb), o que bloqueia <embed> e <object>; não há
`frame_src`, então ele cai em `default_src :self` e o iframe passa. Uma data:
URL seria barrada pelo mesmo fallback. %>
REAL numa prévia recolhível no topo da coluna de edição (partial `_previa`,
que explica por que ela é <details> nativo e não um modal com JavaScript). %>
<div class="space-y-5"
data-controller="romaneio"
data-romaneio-url-value="<%= admin_romaneio_path(@romaneio) %>"
@@ -69,63 +64,22 @@
<%= render 'operacao' %>
<%= render 'avisos' %>
<%# Duas zonas na tela: VEÍCULOS e a edição. A prévia saiu do fluxo e virou
sobreposição sob demanda (botão "Ver prévia") — antes o <iframe> era montado
em TODO carregamento, e cada montagem gerava um PDF no servidor para
ficar num canto que o operador nem sempre olha. Agora o PDF só é gerado
quando alguém pede para ver. %>
<%# Duas zonas na tela: VEÍCULOS e a edição. A prévia é o bloco fechado no topo
da coluna de edição — o PDF só é gerado quando alguém o abre (antes o
<iframe> era montado em TODO carregamento, gerando um PDF no servidor para
ficar num canto que o operador nem sempre olha). %>
<div class="grid grid-cols-1 lg:grid-cols-[minmax(0,260px)_minmax(0,1fr)] gap-5 items-start">
<div class="lg:sticky lg:top-4">
<%= render 'veiculos' %>
</div>
<div class="space-y-4">
<%= render 'previa' %>
<%= render 'controles' %>
<%= render 'tabela', linhas: @linhas %>
<%= render 'removidas', linhas: @removidas %>
</div>
</div>
<%# ── Prévia em sobreposição ──────────────────────────────────────────────
Fica FORA da grade, ocupando a tela inteira quando aberta. `hidden` no
markup e o src só preenchido na abertura: um iframe com src carrega
mesmo escondido, o que anularia a economia.
<iframe> e não <embed>/<object>: o CSP está em enforcing com
`object_src :none`, e sem `frame_src` ele cai em `default_src :self` —
o iframe de mesma origem passa, os outros dois não.
O fechado/aberto é pela CLASSE `hidden`/`flex`, não só pelo atributo
`hidden`: as utilities do Tailwind são aplicadas depois do preflight,
então `.flex` vence o `[hidden] { display:none }` — com `flex` fixo no
markup o modal nascia aberto, em branco e sem fechar, cobrindo a tela
inteira (caso real: /admin/romaneios/13). O controller troca as classes
e mantém o atributo sincronizado. %>
<div data-romaneio-target="overlay" hidden
data-action="click->romaneio#fecharPorFora keydown.esc@window->romaneio#fecharPreview"
class="fixed inset-0 z-50 hidden items-center justify-center p-3 sm:p-6
bg-black/70 backdrop-blur-sm">
<div class="w-full max-w-6xl h-[92vh] flex flex-col gap-3"
data-romaneio-target="caixaPreview">
<div class="flex items-center justify-between gap-3">
<h2 class="text-white font-semibold">
Prévia — <span data-romaneio-target="tituloPreview"><%= @veiculo %></span>
</h2>
<div class="flex items-center gap-2">
<%= link_to 'Abrir em outra aba',
pdf_admin_romaneio_path(@romaneio, veiculo: @veiculo),
target: '_blank', rel: 'noopener',
class: 'text-sm text-gray-300 hover:text-white px-3 py-2 rounded-lg hover:bg-white/10' %>
<button type="button" data-action="romaneio#fecharPreview"
aria-label="Fechar prévia"
class="min-w-[48px] min-h-[48px] rounded-xl bg-[#1a1a1a] border border-white/10
text-white hover:bg-[#242424]">✕</button>
</div>
</div>
<iframe data-romaneio-target="preview"
class="flex-1 w-full rounded-xl border border-white/10 bg-white"
title="Pré-visualização do romaneio"></iframe>
</div>
</div>
<% end %>
</div>