Merge pull request 'Auto-commit local changes before build (2026-01-03 16:04:10)' (#24) from v20260103-11-reports-view-raw-columns-fix into main
Reviewed-on: #24
This commit is contained in:
commit
6944755dd9
@ -1 +1 @@
|
|||||||
v20260103-10-reports-summary-columns-metadata
|
v20260103-11-reports-view-raw-columns-fix
|
||||||
|
|||||||
@ -180,24 +180,10 @@ def api_reports_create():
|
|||||||
return {"id": r.id}
|
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.
|
# Keep the payload stable so report_config can safely store selected keys.
|
||||||
return {
|
return {
|
||||||
"views": [
|
"views": [
|
||||||
@ -312,6 +298,28 @@ def api_reports_columns():
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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"])
|
@main_bp.route("/api/reports/<int:report_id>", methods=["DELETE"])
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from .routes_shared import * # noqa: F401,F403
|
from .routes_shared import * # noqa: F401,F403
|
||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
|
from .routes_reporting_api import build_report_columns_meta
|
||||||
|
|
||||||
def get_default_report_period():
|
def get_default_report_period():
|
||||||
"""Return default report period (last 7 days)."""
|
"""Return default report period (last 7 days)."""
|
||||||
@ -53,6 +54,7 @@ def reports():
|
|||||||
return render_template(
|
return render_template(
|
||||||
"main/reports.html",
|
"main/reports.html",
|
||||||
initial_reports=items,
|
initial_reports=items,
|
||||||
|
columns_meta=build_report_columns_meta(),
|
||||||
default_period_start=period_start.isoformat(),
|
default_period_start=period_start.isoformat(),
|
||||||
default_period_end=period_end.isoformat(),
|
default_period_end=period_end.isoformat(),
|
||||||
)
|
)
|
||||||
@ -70,4 +72,4 @@ def reports_new():
|
|||||||
)
|
)
|
||||||
customer_items = [{"id": int(c.id), "name": c.name or ""} for c in customers]
|
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)
|
return render_template("main/reports_new.html", initial_customers=customer_items, columns_meta=build_report_columns_meta())
|
||||||
|
|||||||
@ -163,6 +163,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
window.__reportColumnsMeta = {{ columns_meta|tojson }};
|
||||||
window.addEventListener('DOMContentLoaded', function () {
|
window.addEventListener('DOMContentLoaded', function () {
|
||||||
var rawModalEl = document.getElementById('rep_raw_modal');
|
var rawModalEl = document.getElementById('rep_raw_modal');
|
||||||
var rawModal = window.bootstrap ? new bootstrap.Modal(rawModalEl) : null;
|
var rawModal = window.bootstrap ? new bootstrap.Modal(rawModalEl) : null;
|
||||||
@ -175,10 +176,11 @@
|
|||||||
var canDeleteReports = {{ 'true' if active_role in ('admin','operator','reporter') else 'false' }};
|
var canDeleteReports = {{ 'true' if active_role in ('admin','operator','reporter') else 'false' }};
|
||||||
|
|
||||||
var reportsItems = [];
|
var reportsItems = [];
|
||||||
var reportColumnsMeta = null;
|
var reportColumnsMeta = window.__reportColumnsMeta || null;
|
||||||
var rawReportConfig = null;
|
var rawReportConfig = null;
|
||||||
|
|
||||||
function loadReportColumnsMeta() {
|
function loadReportColumnsMeta() {
|
||||||
|
if (reportColumnsMeta) return Promise.resolve();
|
||||||
return fetch('/api/reports/columns', { credentials: 'same-origin' })
|
return fetch('/api/reports/columns', { credentials: 'same-origin' })
|
||||||
.then(function (r) { return r.json(); })
|
.then(function (r) { return r.json(); })
|
||||||
.then(function (j) { reportColumnsMeta = j || null; })
|
.then(function (j) { reportColumnsMeta = j || null; })
|
||||||
@ -283,7 +285,7 @@
|
|||||||
|
|
||||||
if (!items || !items.length) {
|
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>';
|
tbody.innerHTML = '<tr><td colspan="' + String(cols.length || 1) + '" class="text-center text-muted py-4">No rows found.</td></tr>';
|
||||||
updateDownloadLink();
|
setRawDownloadLink();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +304,7 @@
|
|||||||
);
|
);
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
updateDownloadLink();
|
setRawDownloadLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadRawData() {
|
function loadRawData() {
|
||||||
|
|||||||
@ -197,6 +197,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
window.__reportColumnsMeta = {{ columns_meta|tojson }};
|
||||||
window.addEventListener('DOMContentLoaded', function () {
|
window.addEventListener('DOMContentLoaded', function () {
|
||||||
function qs(id) { return document.getElementById(id); }
|
function qs(id) { return document.getElementById(id); }
|
||||||
|
|
||||||
@ -216,7 +217,7 @@
|
|||||||
|
|
||||||
// --- Report content / column selector ---
|
// --- Report content / column selector ---
|
||||||
var repColsView = 'summary';
|
var repColsView = 'summary';
|
||||||
var repColsMeta = null;
|
var repColsMeta = window.__reportColumnsMeta || null;
|
||||||
var repColsSelected = { summary: [], snapshot: [] };
|
var repColsSelected = { summary: [], snapshot: [] };
|
||||||
|
|
||||||
function colsHintText(viewKey) {
|
function colsHintText(viewKey) {
|
||||||
@ -434,6 +435,17 @@
|
|||||||
var area = document.getElementById('rep_cols_available');
|
var area = document.getElementById('rep_cols_available');
|
||||||
if (!area) return;
|
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);
|
showColsLoading(true);
|
||||||
clearColsError();
|
clearColsError();
|
||||||
|
|
||||||
@ -654,4 +666,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -90,6 +90,17 @@
|
|||||||
- Corrected the **Missed** column mapping to use `missed_count` for Summary views instead of snapshot-specific fields.
|
- 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.
|
- 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
|
## v0.1.15
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user