feat: improved asset filter UX - collapsible filter panel, customer/location cascade, status dropdown, assigned_to filter, active filter tags, result count

Backend:
- GET /api/customers — lists all customers for filter dropdown
- GET /api/locations?customer_id=X — cascading locations per customer
- GET /api/users — lists users for assigned_to filter

Frontend:
- Collapsible 'Filters' panel with Customer→Location cascade, Status, Assigned To
- Active filter tags showing what's currently filtering, removable individually
- 'Clear all filters' button to reset all at once
- Result count display ('X assets found')
- Better search placeholder showing searchable fields
- Filter count badge on the toggle button
This commit is contained in:
2026-05-22 18:15:35 -04:00
parent 35ccebb0f0
commit d98a791c96
2 changed files with 325 additions and 28 deletions
+39
View File
@@ -798,6 +798,45 @@ def health():
return {"status": "ok"}
# ─── Customer & Location listing (for filter dropdowns) ─────────────────────
@app.get("/api/customers")
def list_customers():
conn = get_db()
rows = conn.execute(
"SELECT id, name FROM customers ORDER BY name"
).fetchall()
conn.close()
return [dict(r) for r in rows]
@app.get("/api/locations")
def list_locations(customer_id: Optional[int] = Query(None)):
conn = get_db()
if customer_id:
rows = conn.execute(
"SELECT id, customer_id, name FROM locations WHERE customer_id = ? ORDER BY name",
(customer_id,),
).fetchall()
else:
rows = conn.execute(
"SELECT id, customer_id, name FROM locations ORDER BY customer_id, name"
).fetchall()
conn.close()
return [dict(r) for r in rows]
@app.get("/api/users")
def list_users():
conn = get_db()
rows = conn.execute(
"SELECT id, username, role FROM users ORDER BY username"
).fetchall()
conn.close()
return [dict(r) for r in rows]
# ─── Task 4: POST /api/assets ──────────────────────────────────────────────