adobe-to-docusign-migrator/web/static/js/issues.js

141 lines
5.4 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Issues & Warnings view — surfaces all validation problems before migration
import { state } from './state.js';
import { escHtml, formatDate, renderFieldIssues, bindFieldIssueToggles } from './utils.js';
import { navigate } from './router.js';
export function renderIssues() {
const outlet = document.getElementById('router-outlet');
const templates = state.templates || [];
const blocked = templates.filter(t => hasBlockers(t));
const warnings = templates.filter(t =>
!hasBlockers(t) && (hasWarnings(t) || hasFieldIssues(t))
);
if (!state.auth.adobe || !state.auth.docusign) {
outlet.innerHTML = `
<div class="page-header"><div><div class="page-title">Issues &amp; Warnings</div></div></div>
<div class="callout info"><span class="callout-icon"></span>Connect both platforms to see validation results.</div>`;
return;
}
if (!blocked.length && !warnings.length) {
outlet.innerHTML = `
<div class="page-header">
<div>
<div class="page-title">Issues &amp; Warnings</div>
<div class="page-subtitle">${templates.length} templates analyzed</div>
</div>
</div>
<div class="callout success" style="font-size:14px">
<span class="callout-icon">🎉</span>
<div>
<strong>All templates are ready!</strong>
<div style="margin-top:4px">No validation blockers, warnings, or field mapping caveats found across ${templates.length} template${templates.length !== 1 ? 's' : ''}.</div>
</div>
</div>`;
return;
}
outlet.innerHTML = `
<div class="page-header">
<div>
<div class="page-title">Issues &amp; Warnings</div>
<div class="page-subtitle">${templates.length} templates analyzed —
${blocked.length ? `<span style="color:var(--error);font-weight:600">${blocked.length} blocked</span>` : ''}
${blocked.length && warnings.length ? ', ' : ''}
${warnings.length ? `<span style="color:var(--warning);font-weight:600">${warnings.length} with warnings</span>` : ''}
</div>
</div>
<div class="page-actions">
<a href="#/templates" class="btn btn-secondary btn-sm">← All Templates</a>
</div>
</div>
${blocked.length ? `
<div style="margin-bottom:24px">
<div style="font-size:14px;font-weight:700;color:var(--error);margin-bottom:10px">
🚫 Blockers — ${blocked.length} template${blocked.length > 1 ? 's' : ''} will fail migration
</div>
<div class="attention-list">
${blocked.map(t => _blockerItem(t)).join('')}
</div>
</div>` : ''}
${warnings.length ? `
<div>
<div style="font-size:14px;font-weight:700;color:var(--warning);margin-bottom:10px">
⚠ Caveats — ${warnings.length} template${warnings.length > 1 ? 's' : ''} should be reviewed
</div>
<div class="attention-list">
${warnings.map(t => _warningItem(t)).join('')}
</div>
</div>` : ''}
`;
// Migrate Anyway buttons
document.querySelectorAll('.btn-migrate-anyway').forEach(btn => {
btn.addEventListener('click', () => {
import('./migration.js').then(m => m.showOptionsModal([btn.dataset.id]));
});
});
// View Template links
document.querySelectorAll('.btn-view-template').forEach(btn => {
btn.addEventListener('click', () => navigate(`#/templates/${btn.dataset.id}`));
});
bindFieldIssueToggles(outlet);
}
function _blockerItem(t) {
const blockers = t.blockers || [];
return `
<div class="attention-item blocker">
<span class="attention-icon">🚫</span>
<div style="flex:1">
<div class="attention-name">${escHtml(t.name)}</div>
${blockers.map(b => `<div class="attention-detail">• ${escHtml(b)}</div>`).join('')}
<div style="margin-top:6px;font-size:11px;color:var(--text-muted)">Modified ${formatDate(t.adobe_modified)}</div>
</div>
<div class="attention-action" style="display:flex;flex-direction:column;gap:6px;align-items:flex-end">
<button class="btn btn-secondary btn-xs btn-view-template" data-id="${escHtml(t.adobe_id)}">View Detail</button>
</div>
</div>
`;
}
function _warningItem(t) {
const warnings = t.warnings || [];
const fieldIssues = t.field_issues || [];
return `
<div class="attention-item warning">
<span class="attention-icon">⚠️</span>
<div style="flex:1">
<div class="attention-name">${escHtml(t.name)}</div>
${warnings.slice(0, 3).map(w => `<div class="attention-detail">• ${escHtml(w)}</div>`).join('')}
${warnings.length > 3 ? `<div class="attention-detail" style="color:var(--text-muted)">… +${warnings.length - 3} more</div>` : ''}
${fieldIssues.length ? renderFieldIssues(fieldIssues) : ''}
<div style="margin-top:6px;font-size:11px;color:var(--text-muted)">Modified ${formatDate(t.adobe_modified)}</div>
</div>
<div class="attention-action" style="display:flex;flex-direction:column;gap:6px;align-items:flex-end">
<button class="btn btn-primary btn-xs btn-migrate-anyway" data-id="${escHtml(t.adobe_id)}">Migrate Anyway</button>
<button class="btn btn-secondary btn-xs btn-view-template" data-id="${escHtml(t.adobe_id)}">View Detail</button>
</div>
</div>
`;
}
function hasBlockers(t) {
return (t.blockers || []).length > 0;
}
function hasWarnings(t) {
return (t.warnings || []).length > 0;
}
function hasFieldIssues(t) {
return (t.field_issues || []).length > 0;
}