feat(reports): Excel renderer + attachment + archive download
render_excel(report): one worksheet per location — interval table, a line chart,
and a Last/Base/Δ summary per window. Metric-driven, so it tracks whatever metric
set is configured.
- orchestrator: render report.xlsx alongside report.html, attach it to the email
(dry-run until SMTP set), expose xlsx_path. Never lets a spreadsheet error sink
the report.
- reports router: /list includes xlsx_url when present; new
GET /archive/{date}/xlsx serves the saved spreadsheet.
- UI: Recent-reports rows get an "Excel" download link.
Verified: real Feb data -> valid .xlsx (sheet per NRL, interval table + chart +
summary with real values), attachment path runs, both archive routes registered.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -206,9 +206,10 @@ function loadRecentReports(projectId) {
|
||||
}
|
||||
box.innerHTML = j.reports.map(function (rp) {
|
||||
var when = (rp.generated_at || '').replace('T', ' ').slice(0, 16);
|
||||
return '<a href="' + rp.view_url + '" target="_blank" class="flex items-center justify-between px-3 py-2 text-sm hover:bg-gray-50 dark:hover:bg-gray-700">'
|
||||
+ '<span class="font-medium text-gray-800 dark:text-gray-200">Night of ' + rp.night_date + '</span>'
|
||||
+ '<span class="text-xs text-gray-400">' + when + ' UTC</span></a>';
|
||||
var xlsx = rp.xlsx_url ? ' · <a href="' + rp.xlsx_url + '" class="text-indigo-600 dark:text-indigo-400 hover:underline">Excel</a>' : '';
|
||||
return '<div class="flex items-center justify-between px-3 py-2 text-sm">'
|
||||
+ '<a href="' + rp.view_url + '" target="_blank" class="font-medium text-gray-800 dark:text-gray-200 hover:underline">Night of ' + rp.night_date + '</a>'
|
||||
+ '<span class="text-xs text-gray-400">' + when + ' UTC' + xlsx + '</span></div>';
|
||||
}).join('');
|
||||
})
|
||||
.catch(function () { box.innerHTML = '<div class="px-3 py-2 text-xs text-red-500">Failed to load.</div>'; });
|
||||
|
||||
Reference in New Issue
Block a user