mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
[w9-2] Add 90d window, time-window selector, and chart/table toggle (#528)
Backend: widen usage _PeriodType to 24h/7d/30d/90d and add a 90d branch to _parse_period (daily buckets already cover it). TestParsePeriod pins the contract per window. Frontend: UsagePeriod += 90d with a scaleFor helper (replacing 6 inline ternaries) and 90 daily mock points. One generic SegmentedControl primitive (reuses Radix Tabs) drives both the metrics time-window selector (24h/7d/30d/90d) and the per-chart Chart/Table view toggle — one file, two roles. The Token Usage & Costs tab drops 8 hardcoded '24h' hooks for a single period state + selector; the stale '(24h)' cost-card parenthetical goes too. The Performance landing tab gains a TaskStatusChart donut fed by the status counts already on the page (no new hook). Agent/team bar charts gain an inline table view. Co-authored-by: Renn F <rennf93@users.noreply.github.com>
This commit is contained in:
@@ -17,7 +17,7 @@ from unittest.mock import AsyncMock, MagicMock
|
||||
from uuid import UUID
|
||||
|
||||
import pytest
|
||||
from roboco.services.usage import UsageService
|
||||
from roboco.services.usage import UsageService, _parse_period
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Named constants (ruff PLR2004: magic values in comparisons must be named).
|
||||
@@ -101,6 +101,45 @@ def _service_with_execute(*return_values: object) -> UsageService:
|
||||
return UsageService(session)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _parse_period — period string → (start_dt, hours)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestParsePeriod:
|
||||
"""_parse_period maps each period string to (start_dt, hours).
|
||||
|
||||
90d is the new window (W9-2); the others pin the existing contract so a
|
||||
future refactor can't silently drop a window.
|
||||
"""
|
||||
|
||||
_HOURS_PER_DAY = 24
|
||||
|
||||
def test_24h_default(self) -> None:
|
||||
start, hours = _parse_period("24h")
|
||||
assert hours == self._HOURS_PER_DAY
|
||||
elapsed_h = (datetime.datetime.now(datetime.UTC) - start).total_seconds() / 3600
|
||||
assert elapsed_h == pytest.approx(self._HOURS_PER_DAY, abs=1)
|
||||
|
||||
def test_7d(self) -> None:
|
||||
_, hours = _parse_period("7d")
|
||||
assert hours == 7 * self._HOURS_PER_DAY
|
||||
|
||||
def test_30d(self) -> None:
|
||||
_, hours = _parse_period("30d")
|
||||
assert hours == 30 * self._HOURS_PER_DAY
|
||||
|
||||
def test_90d(self) -> None:
|
||||
start, hours = _parse_period("90d")
|
||||
assert hours == 90 * self._HOURS_PER_DAY
|
||||
elapsed_h = (datetime.datetime.now(datetime.UTC) - start).total_seconds() / 3600
|
||||
assert elapsed_h == pytest.approx(90 * self._HOURS_PER_DAY, abs=1)
|
||||
|
||||
def test_unknown_defaults_to_24h(self) -> None:
|
||||
_, hours = _parse_period("bogus")
|
||||
assert hours == self._HOURS_PER_DAY
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# get_summary — trend_pct arithmetic
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user