Dashboard polish

This commit is contained in:
2026-08-11 15:28:29 -04:00
parent f1d46e7ab8
commit 34cb9a5e3e
11 changed files with 150 additions and 76 deletions

View File

@@ -1,15 +1,14 @@
"""Dashboard card: PCs that stopped reporting, and PCs that never started.
"""Dashboard card: PCs that were reporting and have stopped.
Two populations, deliberately not merged. A PC that reported and went quiet is
probably off, moved or broken. A PC that has NEVER reported is worse - not
enrolled, or enrolled against the wrong pc-type, so nothing enforces anything on
it and no backup of it exists. That one hides indefinitely because nothing about
it fails loudly.
Deliberately narrow. A PC that never reported at all is usually a record made by
hand or imported, not a bay that broke, and a PC that is not In Use is silent on
purpose - that is the status doing its job. Both would bury the real signal: a
machine that was working, is not now, and nobody has marked as anything else.
"""
from datetime import datetime, timedelta, timezone
from shopdb.core.models import Asset, AssetType, Setting
from shopdb.core.models import Asset, AssetStatus, AssetType, Setting
URL = '/api/computers/dashboard/quiet'
@@ -18,6 +17,16 @@ def _now():
return datetime.now(timezone.utc).replace(tzinfo=None)
def _inuse(db):
"""The card joins on the status NAME, so a bare statusid will not do."""
status = AssetStatus.query.filter_by(status='In Use').first()
if not status:
status = AssetStatus(status='In Use', isactive=True)
db.session.add(status)
db.session.flush()
return status
def _pc(db, hostname, lastreported='now', isactive=True):
from plugins.computers.models import Computer
@@ -27,7 +36,7 @@ def _pc(db, hostname, lastreported='now', isactive=True):
db.session.add(atype)
db.session.flush()
asset = Asset(assetnumber=hostname, assettypeid=atype.assettypeid,
statusid=1, isactive=isactive)
statusid=_inuse(db).statusid, isactive=isactive)
db.session.add(asset)
db.session.flush()
comp = Computer(assetid=asset.assetid, hostname=hostname)
@@ -51,26 +60,29 @@ def test_a_pc_gone_quiet_is_listed_with_how_long(client, db, auth_headers):
_pc(db, 'QUIETPC', lastreported=72)
[row] = client.get(URL, headers=auth_headers).get_json()['data']
assert row['hostname'] == 'QUIETPC'
assert row['state'] == 'stopped reporting'
assert row['quietdays'] == 3
def test_a_pc_that_never_reported_is_called_out_separately(client, db,
auth_headers):
"""Never-reported is a different fault from gone-quiet: nothing is
enforcing anything on that PC and no backup of it exists."""
def test_a_pc_that_never_reported_is_not_listed(client, db, auth_headers):
"""Usually a hand-made or imported record rather than a bay that broke.
Listing them buries the PCs that actually changed state."""
_pc(db, 'NEVERPC', lastreported=None)
[row] = client.get(URL, headers=auth_headers).get_json()['data']
assert row['state'] == 'never reported'
assert row['lastreported'] is None
assert client.get(URL, headers=auth_headers).get_json()['data'] == []
def test_never_reported_sorts_above_the_merely_quiet(client, db, auth_headers):
"""The order someone should work down the list."""
_pc(db, 'QUIETPC', lastreported=48)
_pc(db, 'NEVERPC', lastreported=None)
rows = client.get(URL, headers=auth_headers).get_json()['data']
assert [r['hostname'] for r in rows] == ['NEVERPC', 'QUIETPC']
def test_a_pc_not_in_use_is_not_listed(client, db, auth_headers):
"""A PC in Repair or Retired is silent on purpose - that is the status
doing its job, not a fault to chase."""
from shopdb.core.models import AssetStatus
repair = AssetStatus.query.filter_by(status='In Repair').first()
if not repair:
repair = AssetStatus(status='In Repair', isactive=True)
db.session.add(repair)
db.session.flush()
comp = _pc(db, 'SHELVED', lastreported=200)
comp.asset.statusid = repair.statusid
db.session.commit()
assert client.get(URL, headers=auth_headers).get_json()['data'] == []
def test_the_longest_silence_comes_first(client, db, auth_headers):