From 0fafc28581378095b9fc53c098fd5708ca6e30a2 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 21 May 2026 16:42:05 -0300 Subject: [PATCH] melissa/templates: layout 2-col + preview antes de duplicar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refatora MelissaDocumentosTemplates seguindo padrao do MelissaAgendaConfig (2-col com sidebar). Dois ajustes pedidos: 1. Layout 2-col (mdt-cols grid 360px + 1fr): - COL 1 (sidebar): "Templates do sistema" — lista vertical compacta com nome/tipo/descricao. Click abre preview. - COL 2 (main): "Seus documentos" + subtitulo + grid de cards dos templates do tenant. - Empty states distintos por coluna. - Mobile (<900px): empilha 1-col. 2. Preview antes de duplicar: - View 'preview' nova (alem de list/create/edit). - Click num template do sistema -> view='preview' (substitui "Seus documentos" no main, sidebar permanece pra navegar). - Header da main muda: nome do template + tipo/desc + 2 botoes (Voltar / Duplicar). - Iframe sandbox=allow-same-origin renderiza HTML completo (cabecalho+corpo+rodape com CSS basico A4-like). - Footer com lista de variaveis {{...}} do template (5 +N). - Item ativo na sidebar destaca borda primary + opacity 1 no icone de visualizar. - Pos-duplicar: volta pra view='list' pra mostrar o novo template no main. UX result: user le antes de copiar (evita lixo em "Seus documentos" de copias que nao queria). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../melissa/MelissaDocumentosTemplates.vue | 489 ++++++++++++++++-- 1 file changed, 441 insertions(+), 48 deletions(-) diff --git a/src/layout/melissa/MelissaDocumentosTemplates.vue b/src/layout/melissa/MelissaDocumentosTemplates.vue index e770243..bb22fd5 100644 --- a/src/layout/melissa/MelissaDocumentosTemplates.vue +++ b/src/layout/melissa/MelissaDocumentosTemplates.vue @@ -9,7 +9,7 @@ * Lógica idêntica à DocumentTemplatesPage (composable * useDocumentTemplates + DocumentTemplateEditor reusado). */ -import { ref, onMounted } from 'vue'; +import { ref, computed, onMounted } from 'vue'; import { useToast } from 'primevue/usetoast'; import { useConfirm } from 'primevue/useconfirm'; @@ -29,11 +29,15 @@ const { fetchTemplates, create, update, remove, duplicate } = useDocumentTemplates(); -// ── Views ─────────────────────────────────────────────── +// ── Views: list | create | edit | preview ─────────────── const view = ref('list'); const editingTemplate = ref({}); const editingId = ref(null); +// Preview de template global (somente leitura) — abre antes de duplicar +// para o usuário ler o conteúdo. Inclui botão "Duplicar" no header. +const previewTemplate = ref(null); + // ── Acoes ─────────────────────────────────────────────── function openCreate() { editingId.value = null; @@ -56,6 +60,56 @@ function openEdit(tpl) { view.value = 'edit'; } +// Preview de template do sistema — leitura + botão Duplicar. +// Clique na sidebar de templates do sistema cai aqui em vez de +// duplicar direto. +function openPreview(tpl) { + previewTemplate.value = tpl; + view.value = 'preview'; +} + +// Monta HTML completo do template (cabeçalho + corpo + rodapé) com +// estilos básicos pra preview legível dentro do iframe. +const previewHtml = computed(() => { + const tpl = previewTemplate.value; + if (!tpl) return ''; + const cabecalho = tpl.cabecalho_html || ''; + const corpo = tpl.corpo_html || ''; + const rodape = tpl.rodape_html || ''; + return ` + + + + + + + ${cabecalho ? `
${cabecalho}
` : ''} +
${corpo}
+ ${rodape ? `` : ''} + +`; +}); + async function onSave(payload) { try { if (view.value === 'create') { @@ -82,7 +136,12 @@ function onDuplicate(tpl) { accept: async () => { try { await duplicate(tpl.id); - toast.add({ severity: 'success', summary: 'Duplicado', detail: `"${tpl.nome_template}" copiado para Meus Templates.`, life: 3000 }); + toast.add({ severity: 'success', summary: 'Duplicado', detail: `"${tpl.nome_template}" copiado para Seus documentos.`, life: 3000 }); + // Se veio do preview, volta pra list pra mostrar o novo template no main + if (view.value === 'preview') { + view.value = 'list'; + previewTemplate.value = null; + } } catch (e) { toast.add({ severity: 'error', summary: 'Erro', detail: e?.message }); } @@ -152,7 +211,8 @@ onMounted(() => { - + + {{ templates.length }} @@ -210,8 +270,8 @@ onMounted(() => {
- -