feat: implement in-memory log buffer, add ICP-Brasil seal assets, and improve SDK parameter handling
This commit is contained in:
+82
-29
@@ -107,6 +107,7 @@
|
||||
letter-spacing: 0.5px;
|
||||
background: linear-gradient(to right, #ffffff, #cbd5e1);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
@@ -671,11 +672,8 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label">Tema do Selo Visual:</label>
|
||||
<select id="pdfSealThemeSelect" class="cert-bar-select">
|
||||
<option value="icp-brasil">ICP-Brasil Institucional (Padrão)</option>
|
||||
<option value="gov-br">Governamental (Gov.br / ITI)</option>
|
||||
<option value="cybercore-modern">CyberCore Moderno</option>
|
||||
<option value="minimal-clean">Minimalista Clássico</option>
|
||||
<option value="custom">🎨 Selo Customizado do Designer</option>
|
||||
<option value="icp-brasil">Selo Padrão ICP-Brasil (Oficial)</option>
|
||||
<option value="custom">🎨 Selo Personalizado do Designer</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1031,7 +1029,31 @@
|
||||
certs.forEach((c) => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = c.id;
|
||||
opt.textContent = `${c.common_name || c.alias} [${c.type}] (${c.device_name || c.provider_id})`;
|
||||
|
||||
let rawName = c.common_name || c.alias || 'Certificado';
|
||||
let displayName = rawName;
|
||||
let docNum = c.cpf || c.cnpj || c.cpf_cnpj || '';
|
||||
|
||||
if (rawName.includes(':')) {
|
||||
const parts = rawName.split(':');
|
||||
displayName = parts[0].trim();
|
||||
docNum = parts[1].trim();
|
||||
}
|
||||
}
|
||||
|
||||
const digits = docNum ? String(docNum).replace(/\D/g, '') : '';
|
||||
let docFormatted = '';
|
||||
if (digits.length === 14) {
|
||||
docFormatted = `CNPJ ${digits.replace(/^(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})$/, '../-')}`;
|
||||
} else if (digits.length === 11) {
|
||||
docFormatted = `CPF ${digits.replace(/^(\d{3})(\d{3})(\d{3})(\d{2})$/, '..-')}`;
|
||||
} else if (docNum) {
|
||||
docFormatted = docNum;
|
||||
}
|
||||
|
||||
const typeStr = `[${c.type || 'A1'}]`;
|
||||
const text = docFormatted ? `${displayName}, ${docFormatted} ${typeStr}` : `${displayName} ${typeStr}`;
|
||||
opt.textContent = text;
|
||||
certSelect.appendChild(opt);
|
||||
});
|
||||
|
||||
@@ -1054,9 +1076,25 @@
|
||||
certValidityText.textContent = `Validade: ${cert.valid_to ? new Date(cert.valid_to).toLocaleDateString() : 'N/D'}`;
|
||||
|
||||
if (pdfStampPicker) {
|
||||
const rawDoc = cert.cpf || cert.cnpj || cert.cpf_cnpj || '';
|
||||
const digits = String(rawDoc).replace(/\D/g, '');
|
||||
let docStr = '';
|
||||
if (digits.length === 14) {
|
||||
docStr = `CNPJ: ${digits.replace(/^(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})$/, '../-')}`;
|
||||
} else if (digits.length === 11) {
|
||||
docStr = `CPF: ${digits.replace(/^(\d{3})(\d{3})(\d{3})(\d{2})$/, '..-')}`;
|
||||
} else {
|
||||
docStr = cert.type === 'A3' ? 'Token Físico A3' : 'ICP-Brasil';
|
||||
}
|
||||
|
||||
let cleanSignerName = cert.common_name || cert.alias || 'Titular';
|
||||
if (cleanSignerName && cleanSignerName.includes(':')) {
|
||||
cleanSignerName = cleanSignerName.split(':')[0].trim();
|
||||
}
|
||||
|
||||
pdfStampPicker.updateSealTheme(null, {
|
||||
signerName: cert.common_name || cert.alias,
|
||||
signerDoc: cert.cpf_cnpj ? `CPF: ${cert.cpf_cnpj}` : (cert.type === 'A3' ? 'Token Físico A3' : 'ICP-Brasil')
|
||||
signerName: cleanSignerName,
|
||||
signerDoc: docStr
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@@ -1209,10 +1247,15 @@
|
||||
// Sincroniza alteração de tema com o selo sobre o PDF
|
||||
pdfSealThemeSelect.addEventListener('change', () => {
|
||||
const themeVal = pdfSealThemeSelect.value;
|
||||
if (pdfStampPicker) {
|
||||
if (themeVal === 'custom' && currentCustomSealConfig) {
|
||||
if (themeVal === 'custom') {
|
||||
if (!currentCustomSealConfig && typeof pdfSealDesigner !== 'undefined' && pdfSealDesigner) {
|
||||
currentCustomSealConfig = pdfSealDesigner.getConfig();
|
||||
}
|
||||
if (pdfStampPicker && currentCustomSealConfig) {
|
||||
pdfStampPicker.updateSealTheme(currentCustomSealConfig);
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (pdfStampPicker) {
|
||||
pdfStampPicker.updateSealTheme(themeVal);
|
||||
}
|
||||
}
|
||||
@@ -1230,21 +1273,29 @@
|
||||
const stampConfig = pdfStampPicker ? pdfStampPicker.getStampConfig() : { page: 1, x: 50, y: 50, scale: 1.0 };
|
||||
const selectedTheme = pdfSealThemeSelect.value;
|
||||
|
||||
let effectiveCustomSeal = null;
|
||||
if (selectedTheme === 'custom') {
|
||||
if (currentCustomSealConfig) {
|
||||
effectiveCustomSeal = currentCustomSealConfig;
|
||||
} else if (typeof pdfSealDesigner !== 'undefined' && pdfSealDesigner) {
|
||||
effectiveCustomSeal = pdfSealDesigner.getConfig();
|
||||
currentCustomSealConfig = effectiveCustomSeal;
|
||||
}
|
||||
}
|
||||
|
||||
const signParams = {
|
||||
certificateId: selectedCertificateId,
|
||||
pdf: currentPdfFile || currentPdfBytes,
|
||||
page: stampConfig.page,
|
||||
x: stampConfig.x,
|
||||
y: stampConfig.y,
|
||||
scale: stampConfig.scale
|
||||
scale: stampConfig.scale,
|
||||
sealCustom: effectiveCustomSeal,
|
||||
seal_custom: effectiveCustomSeal,
|
||||
sealThemeId: (selectedTheme === 'custom' ? null : selectedTheme),
|
||||
seal_theme_id: (selectedTheme === 'custom' ? null : selectedTheme)
|
||||
};
|
||||
|
||||
if (selectedTheme === 'custom' && currentCustomSealConfig) {
|
||||
signParams.seal_custom = currentCustomSealConfig;
|
||||
} else {
|
||||
signParams.seal_theme_id = selectedTheme === 'custom' ? 'icp-brasil' : selectedTheme;
|
||||
}
|
||||
|
||||
const result = await signer.signPdfDocument(signParams);
|
||||
|
||||
pdfAlert.className = 'alert alert-success';
|
||||
@@ -1322,22 +1373,24 @@
|
||||
const mount = document.getElementById('sealDesignerMount');
|
||||
pdfSealDesigner = new PdfSealDesigner({
|
||||
container: mount,
|
||||
initialConfig: {
|
||||
initialTheme: {
|
||||
name: 'Selo Customizado',
|
||||
title: 'ASSINADO DIGITALMENTE',
|
||||
primary_color: '#0284c7',
|
||||
secondary_color: '#10b981',
|
||||
background_color: '#ffffff',
|
||||
text_color: '#0f172a',
|
||||
border_color: '#38bdf8',
|
||||
icon_style: 'shield',
|
||||
default_cpf_mode: 'MASKED',
|
||||
default_include_date_time: true
|
||||
customHeader: 'DOCUMENTO ASSINADO DIGITALMENTE',
|
||||
primaryColor: '#0284c7',
|
||||
secondaryColor: '#10b981',
|
||||
backgroundColor: '#ffffff',
|
||||
textColor: '#0f172a',
|
||||
borderColor: '#38bdf8',
|
||||
iconStyle: 'shield',
|
||||
defaultCpfMode: 'MASKED',
|
||||
defaultIncludeDateTime: true
|
||||
},
|
||||
onConfigChange: (cfg) => {
|
||||
onChange: (cfg) => {
|
||||
currentCustomSealConfig = cfg;
|
||||
}
|
||||
});
|
||||
// Inicializa currentCustomSealConfig com o estado atual do designer
|
||||
currentCustomSealConfig = pdfSealDesigner.getConfig();
|
||||
|
||||
// Botão para aplicar o selo na aba de PDF
|
||||
const applyBtnWrap = document.createElement('div');
|
||||
|
||||
Reference in New Issue
Block a user