Integrar el Visor de Documentos
El Visor de Documentos es un componente web que permite a los usuarios editar plantillas y preparar documentos para firmar, directamente dentro de tu aplicación. Esta guía muestra cómo conectarlo a la API GraphQL para construir un flujo de trabajo completo de firma.
Descripción general
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 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 de destinatario y rol del visor
Autenticación
El visor necesita un token válido pasado a su atributo token. Consulta Autenticarse con la API antes de conectar el visor a tu aplicación.
Modo Componer — Enviar un Documento Preconstruido
El modo Componer es para flujos donde tu sistema ya conoce a los destinatarios. El usuario solo coloca los 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 agrega 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— proporciona el estado actual de la plantilla, incluyendo elroleIdpara 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 vincula a cada destinatario con sus campos en la plantilla. Inclúyelo cuando tu flujo de envío necesite ese mapeo.
3. Enviar el documento
Cuando el usuario hace clic en enviar, llama a la mutación send con los datos de destinatario 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 alcance COMPLETED o FAILED para confirmar que la creación del documento ha finalizado.
Modo Editor — Creación de Plantillas
El modo Editor ofrece a los usuarios la experiencia completa de edición de plantillas — añadiendo roles, colocando campos, configurando opciones. Úsalo cuando quieras que los usuarios creen plantillas reutilizables.
<ls-document-viewer
id="editor"
templateid="dHBsYjQ5YTg5NWQtYWRhMy0xMWYwLWIxZGMtMDY5NzZlZmU0MzIx"
token="YOUR_ACCESS_TOKEN"
mode="editor"
></ls-document-viewer>
En 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 persistir 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 añadir un testigo para un firmante, configura roleType: "WITNESS" y usa un signerIndex que sea el índice del firmante principal + 100. Por ejemplo, un testigo del 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 tras la composición |
atributo token | — | Token de la autenticación |
mode="compose" | — | Modo optimizado para colocar campos y enviar |
mode="editor" | — | Modo completo de edición de plantilla |
experience en el input de send | Experience | Controla el branding, correos electrónicos y página de firma — ver Experiencias explicadas |
Relacionados
- Referencia del Visor de Documentos — referencia completa de atributos y eventos
- mutación send — enviar un documento
- DocumentSendSettingsInput — estructura completa del input de envío
- Explicación de métodos de envío — send vs sendBatch vs sendBulk
- Subir un archivo como plantilla — subir plantillas vía API
- Autenticación — elegir un modo de autenticación