feat: custom date range filter on calendar page

- Backend: /api/eco/calendar accepts date_from + date_to query params
  when period=custom; get_calendar() uses them directly without override
  Limit raised to 5000 for wide date ranges
- Frontend: "Custom" tab at end of period list; shows two date inputs
  (from/to) with Apply button; displays day count; fetches on Apply click
  (not on every keystroke to avoid hammering the API)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OpenSquared
2026-06-26 17:17:01 +02:00
parent c36b2b2198
commit d9762deca7
3 changed files with 69 additions and 17 deletions

View File

@@ -421,10 +421,12 @@ def ff_scrape_status_ep() -> Dict[str, Any]:
@router.get("/calendar")
def ff_calendar(
period: str = Query("recent", description="recent|today|tomorrow|yesterday|this_week|next_week|previous_week|this_month|next_month|previous_month"),
period: str = Query("recent", description="recent|today|tomorrow|yesterday|this_week|next_week|previous_week|this_month|next_month|previous_month|custom"),
date_from: Optional[str] = Query(None, description="YYYY-MM-DD (used when period=custom)"),
date_to: Optional[str] = Query(None, description="YYYY-MM-DD (used when period=custom)"),
currencies: Optional[str] = Query(None, description="Comma-separated: USD,EUR,GBP,..."),
impacts: Optional[str] = Query(None, description="Comma-separated: high,medium,low"),
limit: int = Query(300, ge=1, le=2000),
limit: int = Query(500, ge=1, le=5000),
offset: int = Query(0, ge=0),
) -> Dict[str, Any]:
"""Unified Forex Factory calendar — past releases + upcoming events."""
@@ -433,6 +435,8 @@ def ff_calendar(
imp_list = [i.strip().lower() for i in impacts.split(",") if i.strip()] if impacts else None
return get_calendar(
period=period,
date_from=date_from,
date_to=date_to,
currencies=cur_list,
impacts=imp_list,
limit=limit,

View File

@@ -232,6 +232,8 @@ def sync_live() -> Dict[str, Any]:
def get_calendar(
period: str = "recent",
date_from: Optional[str] = None,
date_to: Optional[str] = None,
currencies: Optional[List[str]] = None,
impacts: Optional[List[str]] = None,
limit: int = 300,
@@ -243,6 +245,7 @@ def get_calendar(
period options:
recent | today | tomorrow | yesterday | this_week | next_week |
previous_week | this_month | next_month | previous_month | custom
When period=custom, date_from and date_to are used directly.
"""
from services.database import get_conn
@@ -250,10 +253,14 @@ def get_calendar(
monday = today - timedelta(days=today.weekday())
sunday = monday + timedelta(days=6)
date_from: Optional[str] = None
date_to: Optional[str] = None
# For custom period, date_from/date_to come from the caller — don't override
if period != "custom":
date_from = None
date_to = None
if period == "today":
if period == "custom":
pass # date_from / date_to already set by caller
elif period == "today":
date_from = date_to = str(today)
elif period == "tomorrow":
t = today + timedelta(days=1)