Timeline: document upload, upgraded prompt, CSV export, date_type badge
This commit is contained in:
+33
-7
@@ -3,6 +3,8 @@ const state = {
|
||||
authenticated: Boolean(window.DBN_TOOLS_AUTHENTICATED),
|
||||
};
|
||||
|
||||
let lastTimelineEvents = [];
|
||||
|
||||
const tools = {
|
||||
ask: {
|
||||
kind: 'Source-grounded Legal Ask',
|
||||
@@ -99,6 +101,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
els.healthButton.addEventListener('click', checkHealth);
|
||||
setupUpload();
|
||||
setupAliases();
|
||||
els.results.addEventListener('click', (e) => {
|
||||
if (e.target.closest('#exportCsvBtn')) exportTimelineCSV(lastTimelineEvents);
|
||||
});
|
||||
setTool(state.activeTool);
|
||||
|
||||
if (state.authenticated) {
|
||||
@@ -125,7 +130,7 @@ function setTool(toolName) {
|
||||
els.input.placeholder = tool.placeholder;
|
||||
els.languageControl.classList.toggle('is-hidden', !tool.usesLanguage);
|
||||
els.redactionControl.classList.toggle('is-hidden', toolName !== 'redact');
|
||||
els.uploadZone.classList.toggle('is-hidden', toolName !== 'redact');
|
||||
els.uploadZone.classList.toggle('is-hidden', toolName !== 'redact' && toolName !== 'timeline');
|
||||
els.aliasSection.classList.toggle('is-hidden', toolName !== 'redact');
|
||||
resetUpload();
|
||||
resetAliases();
|
||||
@@ -421,7 +426,11 @@ function renderMainFinding(data) {
|
||||
return `<pre class="redacted-output">${escapeHtml(data.redacted_text || '')}</pre>${renderEntityCounts(data.entity_counts)}`;
|
||||
}
|
||||
if (data.tool === 'timeline') {
|
||||
return `<p>${escapeHtml(data.what_we_found || '')}</p>${renderTimeline(data.events || [])}`;
|
||||
lastTimelineEvents = data.events || [];
|
||||
const csvBtn = lastTimelineEvents.length
|
||||
? `<div class="timeline-export"><button type="button" id="exportCsvBtn" class="export-csv-btn">Download CSV</button></div>`
|
||||
: '';
|
||||
return `<p>${escapeHtml(data.what_we_found || '')}</p>${renderTimeline(lastTimelineEvents)}${csvBtn}`;
|
||||
}
|
||||
if (data.tool === 'summarize') {
|
||||
return [
|
||||
@@ -477,16 +486,33 @@ function renderTimeline(events) {
|
||||
if (!events.length) {
|
||||
return '<p>No events were identified.</p>';
|
||||
}
|
||||
return `<ol class="timeline-list">${events.map((event) => `
|
||||
return `<ol class="timeline-list">${events.map((ev) => `
|
||||
<li>
|
||||
<strong>${escapeHtml(event.date || 'unknown')}</strong>
|
||||
<span>${escapeHtml(event.actor || 'unknown actor')}</span>
|
||||
<p>${escapeHtml(event.event || '')}</p>
|
||||
${event.source_excerpt ? `<small>${escapeHtml(event.source_excerpt)}</small>` : ''}
|
||||
<strong>${escapeHtml(ev.date || 'unknown')}</strong>
|
||||
${ev.date_type ? `<span class="date-type-badge">${escapeHtml(ev.date_type)}</span>` : ''}
|
||||
<span>${escapeHtml(ev.actor || 'unknown actor')}</span>
|
||||
<p>${escapeHtml(ev.event || '')}</p>
|
||||
${ev.source_excerpt ? `<small>${escapeHtml(ev.source_excerpt)}</small>` : ''}
|
||||
</li>
|
||||
`).join('')}</ol>`;
|
||||
}
|
||||
|
||||
function exportTimelineCSV(events) {
|
||||
const header = ['Date', 'Date Type', 'Actor', 'Event', 'Source Excerpt', 'Confidence'];
|
||||
const rows = events.map((ev) => [
|
||||
ev.date || '', ev.date_type || '', ev.actor || '',
|
||||
ev.event || '', ev.source_excerpt || '', ev.confidence || '',
|
||||
]);
|
||||
const csv = [header, ...rows]
|
||||
.map((row) => row.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(','))
|
||||
.join('\n');
|
||||
const blob = new Blob([csv], { type: 'text/csv' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = Object.assign(document.createElement('a'), { href: url, download: 'timeline.csv' });
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
function renderEntityCounts(counts = {}) {
|
||||
const entries = Object.entries(counts).filter(([, count]) => Number(count) > 0);
|
||||
if (!entries.length) {
|
||||
|
||||
Reference in New Issue
Block a user