feat(ui-phase-18): issues & warnings view with nav badge
Dedicated view surfacing all templates with blockers (migration will fail) and warnings (migration with caveats). Each blocker item shows all error messages; each warning item has a Migrate Anyway button and View Detail link. Nav badge count driven by state.issueCount (updated when templates load). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
587104d520
commit
329edc39d2
|
|
@ -0,0 +1,124 @@
|
||||||
|
// Issues & Warnings view — surfaces all validation problems before migration
|
||||||
|
|
||||||
|
import { state } from './state.js';
|
||||||
|
import { escHtml, formatDate } 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 => t.blockers && t.blockers.length > 0);
|
||||||
|
const warnings = templates.filter(t =>
|
||||||
|
(!t.blockers || t.blockers.length === 0) && t.warnings && t.warnings.length > 0
|
||||||
|
);
|
||||||
|
|
||||||
|
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 blockers or warnings 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">
|
||||||
|
⚠ Warnings — ${warnings.length} template${warnings.length > 1 ? 's' : ''} will migrate with caveats
|
||||||
|
</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}`));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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 || [];
|
||||||
|
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>` : ''}
|
||||||
|
<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>
|
||||||
|
`;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue