Jul 16 - Fill the gaps between Single-tenant mode and Multi-tenant mode - MT6

This commit is contained in:
2026-07-16 17:28:10 -04:00
parent 02b030b1d2
commit 253291d5a4
2 changed files with 79 additions and 11 deletions
+54 -8
View File
@@ -105,7 +105,17 @@
<div class="row mb-4">
<div class="col-lg-8 mb-3">
<div class="card shadow-sm h-100">
<div class="card-header bg-light"><h6 class="mb-0"><i class="bi bi-building"></i> Avg Score by Facility</h6></div>
<div class="card-header bg-light d-flex justify-content-between align-items-center gap-2 flex-wrap">
<h6 class="mb-0"><i class="bi bi-building"></i> Avg Score by Facility</h6>
{% if score_contracts %}
<select id="scoreContractFilter" class="form-select form-select-sm" style="max-width:230px;">
<option value="">All Contracts</option>
{% for pid, cname in score_contracts %}
<option value="{{ pid }}">{{ cname }}</option>
{% endfor %}
</select>
{% endif %}
</div>
<div class="card-body"><div class="chart-container"><canvas id="facilityChart"></canvas></div></div>
</div>
</div>
@@ -129,6 +139,7 @@
<thead class="table-light">
<tr>
<th>Facility</th>
<th>Contract</th>
<th class="text-end">Current Period</th>
<th class="text-end">Prior Period</th>
<th class="text-end">Change</th>
@@ -137,8 +148,9 @@
</thead>
<tbody>
{% for row in facility_scores %}
<tr>
<tr class="facility-score-row" data-project-id="{{ row.project_id }}">
<td class="fw-semibold">{{ row.name }}</td>
<td class="text-muted small">{{ row.contract }}</td>
<td class="text-end">
<span class="badge bg-{{ 'success' if row.avg_score >= 90 else 'warning text-dark' if row.avg_score >= 70 else 'danger' }}">
{{ '%.1f'|format(row.avg_score|float) }}%
@@ -266,16 +278,31 @@ new Chart(document.getElementById('trendChart'), {
}
});
// ── Facility bar chart ────────────────────────────────────────────────────────
new Chart(document.getElementById('facilityChart'), {
// ── Facility bar chart (filterable by contract) ───────────────────────────────
const FACILITY_SCORES = {{ facility_scores | tojson }};
let facilityChartObj = null;
function _facColors(data) { return data.map(s => s >= 90 ? GREEN : s >= 70 ? AMBER : RED); }
function renderFacilityChart(pid) {
const rows = (!pid)
? FACILITY_SCORES
: FACILITY_SCORES.filter(r => String(r.project_id) === String(pid));
const labels = rows.map(r => r.name);
const data = rows.map(r => r.avg_score);
if (facilityChartObj) {
facilityChartObj.data.labels = labels;
facilityChartObj.data.datasets[0].data = data;
facilityChartObj.data.datasets[0].backgroundColor = _facColors(data);
facilityChartObj.update();
return;
}
facilityChartObj = new Chart(document.getElementById('facilityChart'), {
type: 'bar',
data: {
labels: {{ facility_scores | map(attribute='name') | list | tojson }},
labels: labels,
datasets: [{
label: 'Avg Score (%)',
data: {{ facility_scores | map(attribute='avg_score') | list | tojson }},
backgroundColor: {{ facility_scores | map(attribute='avg_score') | list | tojson }}
.map(s => s >= 90 ? GREEN : s >= 70 ? AMBER : RED),
data: data,
backgroundColor: _facColors(data),
borderRadius: 4,
}]
},
@@ -285,6 +312,25 @@ new Chart(document.getElementById('facilityChart'), {
plugins: { legend: { display: false } }
}
});
}
function filterFacilityScoreTable(pid) {
document.querySelectorAll('.facility-score-row').forEach(function (tr) {
const rp = tr.getAttribute('data-project-id');
tr.style.display = (!pid || rp === String(pid)) ? '' : 'none';
});
}
(function () {
renderFacilityChart('');
const sel = document.getElementById('scoreContractFilter');
if (sel) {
sel.addEventListener('change', function () {
renderFacilityChart(this.value);
filterFacilityScoreTable(this.value);
});
}
}());
// ── Severity doughnut ─────────────────────────────────────────────────────────
const sevData = {{ issue_severity | tojson }};