Integrar el Visor de Documentos
El Visor de Documentos es un componente web que permite a los usuarios editar plantillas y preparar documentos para la firma, directamente dentro de tu aplicación. Esta guía muestra cómo conectarlo con la API GraphQL para construir un flujo completo de firma.
Resumen
Una integración típica sigue estos pasos:
- Autenticar — obtener un token para el visor
- Subir una plantilla — a través de la API GraphQL
- Renderizar el visor — pasar el ID de la plantilla y el token
- Capturar eventos — el visor emite eventos
updateyvalidatemientras el usuario trabaja - Enviar el documento — llamar a la mutación
sendcon los datos del destinatario y rol del visor
Autenticación
El visor necesita un token válido pasado a su atributo token. Tu backend puede proporcionar un JWT de SRP o un token de componente de corta duración generado por generateComponentToken. Consulta Autorización de Widget antes de integrar el visor en tu aplicación.
Modo Componer — Enviar un Documento Preconstruido
El modo Componer es para flujos donde tu sistema ya conoce los destinatarios. El usuario solo coloca campos de firma y envía.
1. Renderizar el visor
<ls-document-viewer
id="viewer"
templateid="dHBsYjQ5YTg5NWQtYWRhMy0xMWYwLWIxZGMtMDY5NzZlZmU0MzIx"
token="YOUR_ACCESS_TOKEN"
mode="compose"
recipients='[
{"email": "jane@example.com", "firstname": "Jane", "lastname": "Smith", "signerIndex": 1},
{"email": "john@example.com", "firstname": "John", "lastname": "Doe", "signerIndex": 2}
]'
filtertoolbox="signature|initials|date|text"
>
<span slot="right-button">
<button id="send-btn" disabled>Send</button>
</span>
</ls-document-viewer>
2. Rastrear validación y IDs de rol
Mientras el usuario añade campos, el visor emite eventos. Necesitas dos cosas de estos eventos:
validate— te indica si la plantilla tiene todos los campos requeridos (como mínimo, una firma por destinatario)update— provee el estado actual de la plantilla, incluyendoroleIdpara cada participante cuando necesitas el mapeo de roles de plantilla
const viewer = document.getElementById('viewer');
const sendBtn = document.getElementById('send-btn');
let isValid = false;
const recipientRoles = {};
viewer.addEventListener('validate', (e) => {
isValid = e.detail.valid;
sendBtn.disabled = !isValid;
});
viewer.addEventListener('update', (e) => {
const roles = e.detail.template.roles;
roles.forEach((role) => {
recipientRoles[role.signerIndex] = role.id;
});
});
El roleId del evento update asigna cada destinatario a sus campos en la plantilla. Inclúyelo cuando tu flujo de envío necesite esa asignación.
3. Enviar el documento
Cuando el usuario presiona enviar, llama a la mutación send con los datos de los destinatarios y los IDs de rol capturados del visor:
sendBtn.addEventListener('click', async () => {
const token = '<token-from-authentication-guide>';
const recipients = [
{
firstName: 'Jane',
lastName: 'Smith',
email: 'jane@example.com',
role: 'Signer',
roleId: recipientRoles[1],
signerIndex: 1,
order: 1,
},
{
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
role: 'Signer',
roleId: recipientRoles[2],
signerIndex: 2,
order: 2,
},
];
const response = await fetch('https://graphql.uk.legalesign.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
query: `mutation SendDocument {
send(input: {
groupId: "YOUR_GROUP_ID"
templateId: "dHBsYjQ5YTg5NWQtYWRhMy0xMWYwLWIxZGMtMDY5NzZlZmU0MzIx"
title: "Contract - Jane Smith & John Doe"
recipients: ${JSON.stringify(recipients).replace(/"(\w+)":/g, '$1:')}
sequentialSigning: true
})
}`,
}),
});
const result = await response.json();
const taskId = result.data.send;
// Poll for completion
console.log('Task started:', taskId);
});
La mutación send devuelve un ID de tarea. Consulta la query task y monitorea task.report.status hasta que llegue a COMPLETED o FAILED para confirmar que la creación del documento ha terminado.
Modo Editor — Creación de Plantillas
El modo Editor ofrece a los usuarios la experiencia completa de edición de plantilla: añadir roles, colocar campos, configurar opciones. Usa esto cuando quieras que los usuarios construyan plantillas reutilizables.
<ls-document-viewer
id="editor"
templateid="dHBsYjQ5YTg5NWQtYWRhMy0xMWYwLWIxZGMtMDY5NzZlZmU0MzIx"
token="YOUR_ACCESS_TOKEN"
mode="editor"
></ls-document-viewer>
En el modo editor, el evento update se dispara cada vez que la plantilla cambia. Puedes usar esto para rastrear el estado de la plantilla o mostrar un indicador de guardado:
const editor = document.getElementById('editor');
editor.addEventListener('update', (e) => {
console.log('Template updated:', e.detail);
});
editor.addEventListener('validate', (e) => {
console.log('Template valid:', e.detail.valid);
});
Los cambios en la plantilla se guardan automáticamente por el visor — no necesitas llamar a ninguna mutación GraphQL para guardar las ediciones.
Integración con React
El wrapper de React proporciona la misma funcionalidad con manejo de eventos al estilo React:
import { useState } from 'react';
import { LsDocumentViewer } from 'legalesign-document-viewer-react';
const DocumentCompose = ({ templateId, recipients, token }) => {
const [isValid, setIsValid] = useState(false);
const [roleMap, setRoleMap] = useState({});
const handleValidate = (e) => {
setIsValid(e.detail.valid);
};
const handleUpdate = (e) => {
const roles = e.detail.template.roles;
const map = {};
roles.forEach((role) => {
map[role.signerIndex] = role.id;
});
setRoleMap(map);
};
const handleSend = async () => {
const mappedRecipients = recipients.map((r, i) => ({
...r,
roleId: roleMap[r.signerIndex],
order: i + 1,
}));
const response = await fetch('https://graphql.uk.legalesign.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
query: `mutation SendDocument {
send(input: {
groupId: "YOUR_GROUP_ID"
templateId: "${templateId}"
title: "Document"
recipients: ${JSON.stringify(mappedRecipients).replace(/"(\w+)":/g, '$1:')}
})
}`,
}),
});
const result = await response.json();
console.log('Task ID:', result.data.send);
};
if (!token) return null;
return (
<LsDocumentViewer
templateid={templateId}
token={token}
mode="compose"
recipients={JSON.stringify(recipients)}
onValidate={handleValidate}
onUpdate={handleUpdate}
>
<div slot="right-button">
<button onClick={handleSend} disabled={!isValid}>
Send
</button>
</div>
</LsDocumentViewer>
);
};
Testigos
Para agregar un testigo para un firmante, usa roleType: "WITNESS" y un signerIndex igual al índice del firmante principal + 100. Por ejemplo, un testigo para el firmante 2 tiene signerIndex: 102:
<ls-document-viewer
mode="compose"
recipients='[
{"email": "signer@example.com", "firstname": "Alice", "lastname": "Jones", "signerIndex": 1},
{"email": "signer2@example.com", "firstname": "Bob", "lastname": "Brown", "signerIndex": 2},
{"email": "witness@example.com", "firstname": "Carol", "lastname": "White", "signerIndex": 102, "roleType": "WITNESS"}
]'
...
></ls-document-viewer>
Conceptos Clave
| Concepto del visor | Tipo GraphQL | Descripción |
|---|---|---|
atributo templateid | Template | La plantilla que se está editando o componiendo |
atributo recipients | RecipientInput | Destinatarios pasados al modo componer |
roleId del evento update | Role | Vincula un destinatario con sus campos en la plantilla |
evento validate | — | Indica si la plantilla tiene todos los campos requeridos |
mutación send | send | Envía el documento después de componer |
atributo token | — | Token de la autenticación |
mode="compose" | — | Modo simplificado para colocar campos y enviar |
mode="editor" | — | Modo completo de edición de plantillas |
experience en la entrada send | Experience | Controla la marca, emails y página de firma — consulta Experiencias explicadas |
Relacionados
- Referencia del Visor de Documentos — referencia completa de atributos y eventos
- mutación send — enviar un documento
- DocumentSendSettingsInput — estructura completa de entrada para envío
- Métodos de envío explicados — send vs sendBatch vs sendBulk
- Subir un Archivo como Plantilla — subir plantillas vía API
- Autenticación — elegir un modo de autenticación