Compare commits

..

No commits in common. "6944755dd992d6e885bb456c50d08198e4bdab70" and "5100093be4776ea6a778f4579e9d31b1c784f8a2" have entirely different histories.

6 changed files with 23 additions and 58 deletions

View File

@ -1 +1 @@
v20260103-11-reports-view-raw-columns-fix
v20260103-10-reports-summary-columns-metadata

View File

@ -180,10 +180,24 @@ def api_reports_create():
return {"id": r.id}
@main_bp.route("/api/reports/columns", methods=["GET"])
@login_required
def api_reports_columns():
"""Return column metadata used by the Reports UI.
The UI uses this endpoint for:
- grouped column selectors in the "New report" wizard
- translating column keys into human-readable labels
- sensible default columns per view
Note: Column keys map to fields returned by:
- /api/reports/<id>/data?view=summary
- /api/reports/<id>/data?view=snapshot
"""
err = _require_reporting_role()
if err is not None:
return err
def build_report_columns_meta():
"""Build the column metadata payload for reporting UIs."""
# Keep the payload stable so report_config can safely store selected keys.
return {
"views": [
@ -299,28 +313,6 @@ def build_report_columns_meta():
],
}
@main_bp.route("/api/reports/columns", methods=["GET"])
@login_required
def api_reports_columns():
"""Return column metadata used by the Reports UI.
The UI uses this endpoint for:
- grouped column selectors in the "New report" wizard
- translating column keys into human-readable labels
- sensible default columns per view
Note: Column keys map to fields returned by:
- /api/reports/<id>/data?view=summary
- /api/reports/<id>/data?view=snapshot
"""
err = _require_reporting_role()
if err is not None:
return err
# Keep the payload stable so report_config can safely store selected keys.
return build_report_columns_meta()
@main_bp.route("/api/reports/<int:report_id>", methods=["DELETE"])
@login_required

View File

@ -1,6 +1,5 @@
from .routes_shared import * # noqa: F401,F403
from datetime import date, timedelta
from .routes_reporting_api import build_report_columns_meta
def get_default_report_period():
"""Return default report period (last 7 days)."""
@ -54,7 +53,6 @@ def reports():
return render_template(
"main/reports.html",
initial_reports=items,
columns_meta=build_report_columns_meta(),
default_period_start=period_start.isoformat(),
default_period_end=period_end.isoformat(),
)
@ -72,4 +70,4 @@ def reports_new():
)
customer_items = [{"id": int(c.id), "name": c.name or ""} for c in customers]
return render_template("main/reports_new.html", initial_customers=customer_items, columns_meta=build_report_columns_meta())
return render_template("main/reports_new.html", initial_customers=customer_items)

View File

@ -163,7 +163,6 @@
</div>
<script>
window.__reportColumnsMeta = {{ columns_meta|tojson }};
window.addEventListener('DOMContentLoaded', function () {
var rawModalEl = document.getElementById('rep_raw_modal');
var rawModal = window.bootstrap ? new bootstrap.Modal(rawModalEl) : null;
@ -176,11 +175,10 @@
var canDeleteReports = {{ 'true' if active_role in ('admin','operator','reporter') else 'false' }};
var reportsItems = [];
var reportColumnsMeta = window.__reportColumnsMeta || null;
var reportColumnsMeta = null;
var rawReportConfig = null;
function loadReportColumnsMeta() {
if (reportColumnsMeta) return Promise.resolve();
return fetch('/api/reports/columns', { credentials: 'same-origin' })
.then(function (r) { return r.json(); })
.then(function (j) { reportColumnsMeta = j || null; })
@ -285,7 +283,7 @@
if (!items || !items.length) {
tbody.innerHTML = '<tr><td colspan="' + String(cols.length || 1) + '" class="text-center text-muted py-4">No rows found.</td></tr>';
setRawDownloadLink();
updateDownloadLink();
return;
}
@ -304,7 +302,7 @@
);
}).join('');
setRawDownloadLink();
updateDownloadLink();
}
function loadRawData() {

View File

@ -197,7 +197,6 @@
</div>
<script>
window.__reportColumnsMeta = {{ columns_meta|tojson }};
window.addEventListener('DOMContentLoaded', function () {
function qs(id) { return document.getElementById(id); }
@ -217,7 +216,7 @@
// --- Report content / column selector ---
var repColsView = 'summary';
var repColsMeta = window.__reportColumnsMeta || null;
var repColsMeta = null;
var repColsSelected = { summary: [], snapshot: [] };
function colsHintText(viewKey) {
@ -435,17 +434,6 @@
var area = document.getElementById('rep_cols_available');
if (!area) return;
if (repColsMeta) {
showColsLoading(false);
clearColsError();
ensureDefaultsFromMeta();
qs('rep_cols_tab_summary').addEventListener('click', function () { setColsView('summary'); });
qs('rep_cols_tab_snapshot').addEventListener('click', function () { setColsView('snapshot'); });
setColsView('summary');
return;
}
showColsLoading(true);
clearColsError();

View File

@ -90,17 +90,6 @@
- Corrected the **Missed** column mapping to use `missed_count` for Summary views instead of snapshot-specific fields.
- Ensured column metadata is consistent between backend and frontend to allow future graphical output.
---
## v20260103-11-reports-view-raw-columns-fix
### Changed
- Fixed the **View raw** action in Reports by correcting a broken JavaScript function call that prevented raw data from loading.
- Extended the Reports backend to always include column metadata (`columns_meta`) in the response.
- Updated the Reports UI to use embedded column metadata as a fallback, ensuring column selection is available even when an API fetch fails.
- Improved column metadata loading logic to only fetch metadata when it is not already present in the report payload.
================================================================================================================================================
## v0.1.15