feat: add edit session times functionality with modal for monitoring sessions
This commit is contained in:
@@ -20,7 +20,7 @@ import json
|
||||
import logging
|
||||
import io
|
||||
|
||||
from backend.utils.timezone import utc_to_local, format_local_datetime
|
||||
from backend.utils.timezone import utc_to_local, format_local_datetime, local_to_utc
|
||||
|
||||
from backend.database import get_db
|
||||
from fastapi import UploadFile, File
|
||||
@@ -1800,6 +1800,23 @@ async def delete_session(
|
||||
|
||||
VALID_PERIOD_TYPES = {"weekday_day", "weekday_night", "weekend_day", "weekend_night"}
|
||||
|
||||
|
||||
def _derive_period_type(dt: datetime) -> str:
|
||||
is_weekend = dt.weekday() >= 5
|
||||
is_night = dt.hour >= 22 or dt.hour < 7
|
||||
if is_weekend:
|
||||
return "weekend_night" if is_night else "weekend_day"
|
||||
return "weekday_night" if is_night else "weekday_day"
|
||||
|
||||
|
||||
def _build_session_label(dt: datetime, location_name: str, period_type: str) -> str:
|
||||
day_abbr = dt.strftime("%a")
|
||||
date_str = f"{dt.month}/{dt.day}"
|
||||
period_str = {"weekday_day": "Day", "weekday_night": "Night", "weekend_day": "Day", "weekend_night": "Night"}.get(period_type, "")
|
||||
parts = [p for p in [location_name, f"{day_abbr} {date_str}", period_str] if p]
|
||||
return " — ".join(parts)
|
||||
|
||||
|
||||
@router.patch("/{project_id}/sessions/{session_id}")
|
||||
async def patch_session(
|
||||
project_id: str,
|
||||
@@ -1807,13 +1824,53 @@ async def patch_session(
|
||||
data: dict,
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""Update session_label and/or period_type on a monitoring session."""
|
||||
"""Update session fields: started_at, stopped_at, session_label, period_type."""
|
||||
session = db.query(MonitoringSession).filter_by(id=session_id).first()
|
||||
if not session:
|
||||
raise HTTPException(status_code=404, detail="Session not found")
|
||||
if session.project_id != project_id:
|
||||
raise HTTPException(status_code=403, detail="Session does not belong to this project")
|
||||
|
||||
times_changed = False
|
||||
|
||||
if "started_at" in data and data["started_at"]:
|
||||
try:
|
||||
local_dt = datetime.fromisoformat(data["started_at"])
|
||||
session.started_at = local_to_utc(local_dt)
|
||||
times_changed = True
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=400, detail="Invalid started_at datetime format")
|
||||
|
||||
if "stopped_at" in data:
|
||||
if data["stopped_at"]:
|
||||
try:
|
||||
local_dt = datetime.fromisoformat(data["stopped_at"])
|
||||
session.stopped_at = local_to_utc(local_dt)
|
||||
times_changed = True
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=400, detail="Invalid stopped_at datetime format")
|
||||
else:
|
||||
session.stopped_at = None
|
||||
times_changed = True
|
||||
|
||||
if times_changed and session.started_at and session.stopped_at:
|
||||
delta = session.stopped_at - session.started_at
|
||||
session.duration_seconds = max(0, int(delta.total_seconds()))
|
||||
elif times_changed and not session.stopped_at:
|
||||
session.duration_seconds = None
|
||||
|
||||
# Re-derive period_type and session_label from new started_at unless explicitly provided
|
||||
if times_changed and session.started_at and "period_type" not in data:
|
||||
local_start = utc_to_local(session.started_at)
|
||||
session.period_type = _derive_period_type(local_start)
|
||||
|
||||
if times_changed and session.started_at and "session_label" not in data:
|
||||
from backend.models import MonitoringLocation
|
||||
location = db.query(MonitoringLocation).filter_by(id=session.location_id).first()
|
||||
location_name = location.name if location else ""
|
||||
local_start = utc_to_local(session.started_at)
|
||||
session.session_label = _build_session_label(local_start, location_name, session.period_type or "")
|
||||
|
||||
if "session_label" in data:
|
||||
session.session_label = str(data["session_label"]).strip() or None
|
||||
if "period_type" in data:
|
||||
|
||||
Reference in New Issue
Block a user