06/12 Redesign dashboard 2
This commit is contained in:
+134
-15
@@ -207,6 +207,120 @@ def index():
|
||||
sla_breached = sum(1 for i in all_open_issues if sla_status(i) == 'breached')
|
||||
sla_at_risk = sum(1 for i in all_open_issues if sla_status(i) == 'at_risk')
|
||||
|
||||
# ── Issues opened today ───────────────────────────────────────────────────
|
||||
from app.models.facility import Area as _AreaT
|
||||
opened_today_q = Issue.query.outerjoin(_AreaT, Issue.area_id == _AreaT.id).filter(
|
||||
Issue.reported_at >= today_start,
|
||||
Issue.reported_at < today_end,
|
||||
)
|
||||
if is_inspector:
|
||||
if not inspector_facility_ids:
|
||||
opened_today_q = opened_today_q.filter(False)
|
||||
else:
|
||||
opened_today_q = opened_today_q.filter(db.or_(
|
||||
Issue.facility_id.in_(inspector_facility_ids),
|
||||
_AreaT.facility_id.in_(inspector_facility_ids),
|
||||
))
|
||||
elif is_customer:
|
||||
if not customer_facility_ids:
|
||||
opened_today_q = opened_today_q.filter(False)
|
||||
else:
|
||||
opened_today_q = opened_today_q.filter(db.or_(
|
||||
Issue.facility_id.in_(customer_facility_ids),
|
||||
_AreaT.facility_id.in_(customer_facility_ids),
|
||||
))
|
||||
issues_opened_today = opened_today_q.count()
|
||||
|
||||
# ── Pending verification ──────────────────────────────────────────────────
|
||||
from app.models.facility import Area as _AreaV
|
||||
pv_q = Issue.query.outerjoin(_AreaV, Issue.area_id == _AreaV.id).filter(
|
||||
Issue.status == 'pending_verification',
|
||||
)
|
||||
if is_inspector:
|
||||
if not inspector_facility_ids:
|
||||
pv_q = pv_q.filter(False)
|
||||
else:
|
||||
pv_q = pv_q.filter(db.or_(
|
||||
Issue.facility_id.in_(inspector_facility_ids),
|
||||
_AreaV.facility_id.in_(inspector_facility_ids),
|
||||
))
|
||||
elif is_customer:
|
||||
if not customer_facility_ids:
|
||||
pv_q = pv_q.filter(False)
|
||||
else:
|
||||
pv_q = pv_q.filter(db.or_(
|
||||
Issue.facility_id.in_(customer_facility_ids),
|
||||
_AreaV.facility_id.in_(customer_facility_ids),
|
||||
))
|
||||
pending_verification = pv_q.count()
|
||||
|
||||
# ── Stale in-progress inspections (started > 24h ago, not yet submitted) ──
|
||||
stale_cutoff = now - timedelta(hours=24)
|
||||
stale_q = Inspection.query.filter(
|
||||
Inspection.status == 'in_progress',
|
||||
Inspection.inspection_date < stale_cutoff,
|
||||
)
|
||||
if is_inspector:
|
||||
if not inspector_facility_ids:
|
||||
stale_q = stale_q.filter(False)
|
||||
else:
|
||||
stale_q = stale_q.filter(
|
||||
Inspection.facility_id.in_(inspector_facility_ids),
|
||||
Inspection.inspector_id == current_user.id,
|
||||
)
|
||||
elif is_customer:
|
||||
if customer_facility_ids:
|
||||
stale_q = stale_q.filter(Inspection.facility_id.in_(customer_facility_ids))
|
||||
else:
|
||||
stale_q = stale_q.filter(False)
|
||||
stale_in_progress = stale_q.count()
|
||||
|
||||
# ── Unassigned open issues ────────────────────────────────────────────────
|
||||
from app.models.facility import Area as _AreaU
|
||||
unassigned_q = Issue.query.outerjoin(_AreaU, Issue.area_id == _AreaU.id).filter(
|
||||
Issue.status.in_(['open', 'in_progress']),
|
||||
Issue.assigned_to.is_(None),
|
||||
)
|
||||
if is_inspector:
|
||||
if not inspector_facility_ids:
|
||||
unassigned_q = unassigned_q.filter(False)
|
||||
else:
|
||||
unassigned_q = unassigned_q.filter(db.or_(
|
||||
Issue.facility_id.in_(inspector_facility_ids),
|
||||
_AreaU.facility_id.in_(inspector_facility_ids),
|
||||
))
|
||||
elif is_customer:
|
||||
unassigned_q = unassigned_q.filter(False) # not relevant for customers
|
||||
unassigned_open = unassigned_q.count()
|
||||
|
||||
# ── Inspector activity today (admin / director / PM only) ─────────────────
|
||||
inspector_activity = []
|
||||
if is_privileged or is_project_manager:
|
||||
active_inspectors = (
|
||||
User.query
|
||||
.filter_by(role='inspector', active=True)
|
||||
.order_by(User.full_name, User.username)
|
||||
.all()
|
||||
)
|
||||
today_counts = dict(
|
||||
db.session.query(
|
||||
Inspection.inspector_id,
|
||||
func.count(Inspection.id),
|
||||
)
|
||||
.filter(
|
||||
Inspection.status == 'completed',
|
||||
Inspection.inspection_date >= today_start,
|
||||
Inspection.inspection_date < today_end,
|
||||
)
|
||||
.group_by(Inspection.inspector_id)
|
||||
.all()
|
||||
)
|
||||
inspector_activity = sorted(
|
||||
[{'name': u.display_name, 'count': today_counts.get(u.id, 0)}
|
||||
for u in active_inspectors],
|
||||
key=lambda x: (-x['count'], x['name']),
|
||||
)
|
||||
|
||||
# ── My open issues (inspector dashboard widget) ───────────────────────────
|
||||
# Issues assigned to the current inspector that are not yet resolved,
|
||||
# ordered by SLA urgency (breached first, then at-risk, then ok).
|
||||
@@ -225,21 +339,26 @@ def index():
|
||||
|
||||
return render_template(
|
||||
'dashboard.html',
|
||||
today_inspections = today_inspections,
|
||||
completed_today = completed_today,
|
||||
open_issues = open_issues,
|
||||
severity_breakdown = severity_breakdown,
|
||||
resolved_today = resolved_today,
|
||||
pending_followups = pending_followups,
|
||||
recent_inspections = recent_inspections,
|
||||
total_facilities = total_facilities,
|
||||
total_templates = total_templates,
|
||||
total_users = total_users,
|
||||
sla_breached = sla_breached,
|
||||
sla_at_risk = sla_at_risk,
|
||||
customer_facilities = customer_facilities,
|
||||
my_issues = my_issues,
|
||||
today_str = now.strftime('%Y-%m-%d'),
|
||||
today_inspections = today_inspections,
|
||||
completed_today = completed_today,
|
||||
open_issues = open_issues,
|
||||
severity_breakdown = severity_breakdown,
|
||||
resolved_today = resolved_today,
|
||||
pending_followups = pending_followups,
|
||||
issues_opened_today = issues_opened_today,
|
||||
pending_verification = pending_verification,
|
||||
stale_in_progress = stale_in_progress,
|
||||
unassigned_open = unassigned_open,
|
||||
inspector_activity = inspector_activity,
|
||||
recent_inspections = recent_inspections,
|
||||
total_facilities = total_facilities,
|
||||
total_templates = total_templates,
|
||||
total_users = total_users,
|
||||
sla_breached = sla_breached,
|
||||
sla_at_risk = sla_at_risk,
|
||||
customer_facilities = customer_facilities,
|
||||
my_issues = my_issues,
|
||||
today_str = now.strftime('%Y-%m-%d'),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user