ADR-013 Phase 3: generic map-overlays renderer (Path A)

Wires the ADR-010 get_map_overlays hook into the floor map so a plugin decorates
markers as JSON, no map code. ShopFloorMap fetches /api/pluginui/map-overlays,
then each overlay's endpoint (per-asset [{assetid, color, label}]), joins by
assetid, and draws a ring or badge circleMarker on matching markers plus a
legend entry - all as extra Leaflet layers cleared and redrawn with the markers.

Aligned the measuringtools calibration overlay endpoint to the documented
contract: it now returns {assetid, color, label} (was {calibrationstatus,
statuscolor}) and only decorates due/overdue tools.

Additive + guarded (assetid null check, per-endpoint try/catch, cleanup on
re-render), so the map degrades to no decorations on any failure. Verified: the
overlay endpoint serves the contract shape, the map renders without error, and
the frontend builds. A populated badge needs a site that actually places
measuring tools on its map (this dataset places none). 38 measuringtools/pluginui
tests, 58 vitest, build + naming green.
This commit is contained in:
cproudlock
2026-07-18 23:10:09 -04:00
parent 8a2f984393
commit 296b6e024b
3 changed files with 105 additions and 6 deletions

View File

@@ -447,10 +447,11 @@ def test_map_overlay_shape_and_derivation(client, auth_headers):
response = client.get('/api/measuringtools/map-overlay')
assert response.status_code == 200, response.get_json()
rows = response.get_json()['data']
# ADR-010 overlay contract: [{assetid, color, label}], only due/overdue tools.
row = next(r for r in rows if r['assetid'] == assetid)
assert set(row) == {'assetid', 'calibrationstatus', 'statuscolor'}
assert row['calibrationstatus'] == 'overdue'
assert row['statuscolor'] == STATUS_COLORS['overdue']
assert set(row) == {'assetid', 'color', 'label'}
assert row['label'] == 'Overdue'
assert row['color'] == STATUS_COLORS['overdue']
def test_map_overlay_excludes_inactive(client, auth_headers):