From 89bf1817426b2278d4856ee55b37a24d55b1f7fa Mon Sep 17 00:00:00 2001 From: Leonardo Date: Fri, 22 May 2026 13:42:39 -0300 Subject: [PATCH] melissa/paciente-docs: wire-up preview actions + Editar abre dialog em modo edicao MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DocumentPreviewDialog emitia @download/@edit/@share/@sign/@delete que o MelissaPatientDocuments nao ouvia — os 5 botoes da sidebar do preview caiam no vazio. Adicionado wire-up roteando pros mesmos handlers do card (onDownload, onEdit, onShare, onSign, onDelete). Share/sign/delete fecham o preview antes de abrir o proprio dialog pra UX limpa; download mantem preview aberto (acao instantanea). DocumentGenerateDialog ganha prop editing-doc-id. Quando setado: - Busca template_id + dados_preenchidos via loadGeneratedFromDocId - Pre-seleciona template, popula vars (sobrescreve auto-loaded vars com dados_preenchidos pra preservar customizacao anterior) - Pula direto pra step 'edit' - Save vira UPDATE in-place (preserva documents.id e audit trail) - Header muda pra "Editar documento" + icone pi-pencil amber - Botao final vira "Substituir documento" - Doc sem registro generated (legado): toast info + flow normal de select template; ao salvar, cria o registro generated linkado. MelissaPatientDocuments: - onEdit substituido (era shortcut pra onPreview): abre generate dialog com editing-doc-id setado. - Novo ref editingDoc dedicado (separado do selectedDoc que serve preview/share/sign/delete) pra evitar vazar "edit state" pro botao "Gerar" do header quando user so abre preview e fecha. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../components/DocumentGenerateDialog.vue | 75 +++++++++++++++---- .../melissa/MelissaPatientDocuments.vue | 29 ++++++- 2 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/features/documents/components/DocumentGenerateDialog.vue b/src/features/documents/components/DocumentGenerateDialog.vue index 361a120..82c7e10 100644 --- a/src/features/documents/components/DocumentGenerateDialog.vue +++ b/src/features/documents/components/DocumentGenerateDialog.vue @@ -13,12 +13,19 @@ import { ref, watch, computed } from 'vue' import { useToast } from 'primevue/usetoast' import { useDocumentGenerate } from '../composables/useDocumentGenerate' import { useDocumentTemplates } from '../composables/useDocumentTemplates' +import { loadGeneratedFromDocId } from '@/services/DocumentGenerate.service' const props = defineProps({ visible: { type: Boolean, default: false }, patientId: { type: String, default: null }, patientName: { type: String, default: '' }, - agendaEventoId: { type: String, default: null } + agendaEventoId: { type: String, default: null }, + // Modo edicao: ID de um documents.id existente. Quando setado, o dialog + // busca o template_id + dados_preenchidos do document_generated vinculado, + // pre-seleciona o template e popula as variaveis. Save vira UPDATE + // in-place (preserva documents.id e audit). Doc sem registro generated + // (uploaded direto) cai no flow normal de "select template". + editingDocId: { type: String, default: null } }) const emit = defineEmits(['update:visible', 'generated']) @@ -52,13 +59,48 @@ const { // ── Reset ao abrir ────────────────────────────────────────── watch(() => props.visible, async (v) => { - if (v) { - step.value = 'select' - reset() - await Promise.all([ - fetchTemplates(), - props.patientId ? loadVariables(props.patientId, props.agendaEventoId) : Promise.resolve() - ]) + if (!v) return; + step.value = 'select' + reset() + await Promise.all([ + fetchTemplates(), + props.patientId ? loadVariables(props.patientId, props.agendaEventoId) : Promise.resolve() + ]) + + // Modo edicao: tenta carregar o registro do generated, pre-seleciona + // template e popula vars com dados_preenchidos (sobrescreve auto-vars + // — preserva customizacao anterior do user). Se nao houver linkage + // (doc uploaded direto), continua no flow normal de "select template". + if (props.editingDocId) { + const gen = await loadGeneratedFromDocId(props.editingDocId) + if (gen?.template_id) { + try { + await selectTemplate(gen.template_id) + // Merge: dados_preenchidos override auto-loaded variables. + // Mantemos as vars que o user nao tinha customizado da vez + // anterior (pra caso o template tenha vars novas adicionadas + // depois) — pegamos as keys auto + sobrescreve com generated. + const saved = gen.dados_preenchidos || {} + Object.entries(saved).forEach(([k, val]) => { + setVariable(k, val == null ? '' : String(val)) + }) + step.value = 'edit' + } catch (e) { + toast.add({ + severity: 'warn', + summary: 'Template original não encontrado', + detail: 'Selecione um template para regenerar o documento.', + life: 3500 + }) + } + } else { + toast.add({ + severity: 'info', + summary: 'Documento legado', + detail: 'Sem dados de edição. Selecione um template para regenerar.', + life: 3500 + }) + } } }) @@ -109,8 +151,15 @@ function onVarChange(key, val) { async function onGenerate() { try { - const result = await generateAndSave(props.patientId) - toast.add({ severity: 'success', summary: 'Documento salvo', detail: 'Disponível nos documentos do paciente.', life: 3000 }) + const result = await generateAndSave(props.patientId, props.editingDocId || null) + toast.add({ + severity: 'success', + summary: props.editingDocId ? 'Documento atualizado' : 'Documento salvo', + detail: props.editingDocId + ? 'PDF substituído com os novos valores.' + : 'Disponível nos documentos do paciente.', + life: 3000 + }) emit('generated', result) close() } catch (e) { @@ -153,10 +202,10 @@ function close() {