feat(plantillas): subir el documento y que la IA lo devuelva como plantilla editable
Hasta ahora crear una plantilla era escribir HTML con variables de Go a mano. Ahora se sube el documento que ya existe (.docx, .html, .txt o una foto del papel), se lee —docx con stdlib, imágenes por OCR— y la IA lo devuelve armado como plantilla con las variables del generador puestas donde iban los datos. No se guarda solo: el HTML cae en el editor para revisarlo, y si la IA devolvió sintaxis de plantilla inválida se avisa antes de guardar. PDF queda afuera por ahora; el mensaje de error dice qué hacer en su lugar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8c3ab79e88
commit
e681f41639
@@ -90,6 +90,24 @@
|
||||
<span class="block mt-1 text-blue-500">Cada tipo de documento pasa campos adicionales propios (ver /api/v2/spec).</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 border border-dashed border-gray-300 rounded p-3 bg-gray-50">
|
||||
<p class="text-xs font-medium text-gray-600 mb-1">¿Ya tenés el documento hecho?</p>
|
||||
<p class="text-xs text-gray-500 mb-2">
|
||||
Subí el archivo (.docx, .html, .txt o una foto/captura del documento) y la IA lo devuelve
|
||||
armado como plantilla, con las variables puestas. Después lo editás acá abajo antes de guardar.
|
||||
</p>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<input type="file" x-ref="archivo" accept=".docx,.html,.htm,.txt,.md,image/*"
|
||||
class="text-xs" />
|
||||
<button type="button" @click="importar()" :disabled="importando"
|
||||
class="px-3 py-1.5 border rounded text-xs disabled:opacity-50">
|
||||
<span x-text="importando ? 'Leyendo…' : 'Leer con IA'"></span>
|
||||
</button>
|
||||
<span x-show="avisoImport" x-text="avisoImport" class="text-xs"
|
||||
:class="errorImport ? 'text-red-600' : 'text-green-600'"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form @submit.prevent="save()">
|
||||
<div class="grid grid-cols-3 gap-3 mb-3">
|
||||
<div>
|
||||
@@ -154,6 +172,7 @@ document.addEventListener('alpine:init', () => {
|
||||
datos: [], total: 0, totalPages: 1, page: 1, limit: 20, filtroTipo: '',
|
||||
addModal: false, editModal: false, deleteModal: false,
|
||||
selectedId: null, templateError: '',
|
||||
importando: false, avisoImport: '', errorImport: false,
|
||||
form: { nombre:'', tipo:'cotizacion', contenido_html:'', version:1, activa:true },
|
||||
toast: { show:false, msg:'', type:'ok' },
|
||||
|
||||
@@ -179,6 +198,26 @@ document.addEventListener('alpine:init', () => {
|
||||
},
|
||||
openDelete(d) { this.selectedId = d.ID; this.deleteModal = true; },
|
||||
|
||||
async importar() {
|
||||
const f = this.$refs.archivo?.files?.[0];
|
||||
if (!f) { this.errorImport = true; this.avisoImport = 'Elegí un archivo primero'; return; }
|
||||
this.importando = true; this.avisoImport = ''; this.errorImport = false;
|
||||
try {
|
||||
const fd = new FormData();
|
||||
fd.append('archivo', f);
|
||||
fd.append('tipo', this.form.tipo);
|
||||
const { data } = await axios.post('/app/api/plantillas-documento/importar', fd);
|
||||
this.form.contenido_html = data.contenido_html || '';
|
||||
if (!this.form.nombre) this.form.nombre = f.name.replace(/\.[^.]+$/, '');
|
||||
this.errorImport = !!data.aviso;
|
||||
this.avisoImport = data.aviso || 'Listo, revisá el HTML abajo';
|
||||
} catch(e) {
|
||||
this.errorImport = true;
|
||||
this.avisoImport = e.response?.data?.error || e.message;
|
||||
}
|
||||
this.importando = false;
|
||||
},
|
||||
|
||||
async validar() {
|
||||
this.templateError = '';
|
||||
},
|
||||
@@ -187,6 +226,7 @@ document.addEventListener('alpine:init', () => {
|
||||
this.addModal = this.editModal = this.deleteModal = false;
|
||||
this.selectedId = null;
|
||||
this.templateError = '';
|
||||
this.avisoImport = ''; this.errorImport = false;
|
||||
this.form = { nombre:'', tipo:'cotizacion', contenido_html:'', version:1, activa:true };
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user