141 lines
5.4 KiB
JavaScript
141 lines
5.4 KiB
JavaScript
// 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 & 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 & 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 & 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;
|
||
}
|