diff --git a/backend/routers/dashboard.py b/backend/routers/dashboard.py index ae1ae51..c9e61bb 100644 --- a/backend/routers/dashboard.py +++ b/backend/routers/dashboard.py @@ -1,7 +1,12 @@ from fastapi import APIRouter, Request, Depends +from sqlalchemy.orm import Session +from datetime import datetime, timedelta +from backend.database import get_db +from backend.models import ScheduledAction, MonitoringLocation, Project from backend.services.snapshot import emit_status_snapshot from backend.templates_config import templates +from backend.utils.timezone import utc_to_local, local_to_utc, get_user_timezone router = APIRouter() @@ -22,3 +27,71 @@ def dashboard_benched(request: Request): "partials/benched_table.html", {"request": request, "units": snapshot["benched"]} ) + + +@router.get("/dashboard/todays-actions") +def dashboard_todays_actions(request: Request, db: Session = Depends(get_db)): + """ + Get today's scheduled actions for the dashboard card. + Shows upcoming, completed, and failed actions for today. + """ + import json + from zoneinfo import ZoneInfo + + # Get today's date range in local timezone + tz = ZoneInfo(get_user_timezone()) + now_local = datetime.now(tz) + today_start_local = now_local.replace(hour=0, minute=0, second=0, microsecond=0) + today_end_local = today_start_local + timedelta(days=1) + + # Convert to UTC for database query + today_start_utc = today_start_local.astimezone(ZoneInfo("UTC")).replace(tzinfo=None) + today_end_utc = today_end_local.astimezone(ZoneInfo("UTC")).replace(tzinfo=None) + + # Query today's actions + actions = db.query(ScheduledAction).filter( + ScheduledAction.scheduled_time >= today_start_utc, + ScheduledAction.scheduled_time < today_end_utc, + ).order_by(ScheduledAction.scheduled_time.asc()).all() + + # Enrich with location/project info and parse results + enriched_actions = [] + for action in actions: + location = None + project = None + if action.location_id: + location = db.query(MonitoringLocation).filter_by(id=action.location_id).first() + if action.project_id: + project = db.query(Project).filter_by(id=action.project_id).first() + + # Parse module_response for result details + result_data = None + if action.module_response: + try: + result_data = json.loads(action.module_response) + except json.JSONDecodeError: + pass + + enriched_actions.append({ + "action": action, + "location": location, + "project": project, + "result": result_data, + }) + + # Count by status + pending_count = sum(1 for a in actions if a.execution_status == "pending") + completed_count = sum(1 for a in actions if a.execution_status == "completed") + failed_count = sum(1 for a in actions if a.execution_status == "failed") + + return templates.TemplateResponse( + "partials/dashboard/todays_actions.html", + { + "request": request, + "actions": enriched_actions, + "pending_count": pending_count, + "completed_count": completed_count, + "failed_count": failed_count, + "total_count": len(actions), + } + ) diff --git a/backend/routers/projects.py b/backend/routers/projects.py index 9b06de5..d2fc991 100644 --- a/backend/routers/projects.py +++ b/backend/routers/projects.py @@ -493,9 +493,18 @@ async def get_project_schedules( "actions": [], } + # Parse module_response for display + result_data = None + if schedule.module_response: + try: + result_data = json.loads(schedule.module_response) + except json.JSONDecodeError: + pass + schedules_by_date[date_key]["actions"].append({ "schedule": schedule, "location": location, + "result": result_data, }) return templates.TemplateResponse("partials/projects/schedule_list.html", { diff --git a/backend/static/icons/favicon-16.png b/backend/static/icons/favicon-16.png new file mode 100644 index 0000000..bb9c326 Binary files /dev/null and b/backend/static/icons/favicon-16.png differ diff --git a/backend/static/icons/favicon-32.png b/backend/static/icons/favicon-32.png new file mode 100644 index 0000000..7c0f5ad Binary files /dev/null and b/backend/static/icons/favicon-32.png differ diff --git a/backend/static/icons/icon-128.png b/backend/static/icons/icon-128.png index 83af799..21eb7cd 100644 Binary files a/backend/static/icons/icon-128.png and b/backend/static/icons/icon-128.png differ diff --git a/backend/static/icons/icon-144.png b/backend/static/icons/icon-144.png index d8d90b5..a454963 100644 Binary files a/backend/static/icons/icon-144.png and b/backend/static/icons/icon-144.png differ diff --git a/backend/static/icons/icon-152.png b/backend/static/icons/icon-152.png index 9ef75af..4d505ac 100644 Binary files a/backend/static/icons/icon-152.png and b/backend/static/icons/icon-152.png differ diff --git a/backend/static/icons/icon-192.png b/backend/static/icons/icon-192.png index 3290b47..9e6ac30 100644 Binary files a/backend/static/icons/icon-192.png and b/backend/static/icons/icon-192.png differ diff --git a/backend/static/icons/icon-384.png b/backend/static/icons/icon-384.png index 2cf0aef..2b5d857 100644 Binary files a/backend/static/icons/icon-384.png and b/backend/static/icons/icon-384.png differ diff --git a/backend/static/icons/icon-512.png b/backend/static/icons/icon-512.png index b2c82dd..1e4b4cd 100644 Binary files a/backend/static/icons/icon-512.png and b/backend/static/icons/icon-512.png differ diff --git a/backend/static/icons/icon-72.png b/backend/static/icons/icon-72.png index d0d0359..1a5a1c1 100644 Binary files a/backend/static/icons/icon-72.png and b/backend/static/icons/icon-72.png differ diff --git a/backend/static/icons/icon-96.png b/backend/static/icons/icon-96.png index cbcff51..a779b31 100644 Binary files a/backend/static/icons/icon-96.png and b/backend/static/icons/icon-96.png differ diff --git a/backend/static/terra-view-logo-dark.png b/backend/static/terra-view-logo-dark.png new file mode 100644 index 0000000..200ff5e Binary files /dev/null and b/backend/static/terra-view-logo-dark.png differ diff --git a/backend/static/terra-view-logo-dark@2x.png b/backend/static/terra-view-logo-dark@2x.png new file mode 100644 index 0000000..96dec0a Binary files /dev/null and b/backend/static/terra-view-logo-dark@2x.png differ diff --git a/backend/static/terra-view-logo-light.png b/backend/static/terra-view-logo-light.png new file mode 100644 index 0000000..5000328 Binary files /dev/null and b/backend/static/terra-view-logo-light.png differ diff --git a/backend/static/terra-view-logo-light@2x.png b/backend/static/terra-view-logo-light@2x.png new file mode 100644 index 0000000..51c0123 Binary files /dev/null and b/backend/static/terra-view-logo-light@2x.png differ diff --git a/templates/base.html b/templates/base.html index e5ecd59..13364aa 100644 --- a/templates/base.html +++ b/templates/base.html @@ -20,6 +20,9 @@ + + + @@ -68,7 +71,7 @@ {% block extra_head %}{% endblock %} - +
@@ -85,10 +88,10 @@