mirror of
https://github.com/coder/coder.git
synced 2026-10-31 19:36:41 +08:00
<img width="1195" height="165" alt="Screenshot 2026-08-19 at 5 31 17 PM" src="https://github.com/user-attachments/assets/d1e49e5f-1af6-4221-87fe-ae40997f0ae7" /> Adds a "Total agent hours" consumption panel to the Licenses page, surfacing the `agent_runtime_hours` entitlement introduced by the #27983 / #27984 / #27985 stack. The new `TotalAgentHoursCard` renders full width directly above the Agent Workspace Builds panel. It shows a usage bar with Used/Limit labels and an info tooltip next to the title. The bar color and tooltip copy track the same thresholds the backend uses for license warnings: green below the soft limit, orange once usage reaches the soft limit, and red once usage reaches the purchased allocation (values at or beyond the threshold count as reached, matching `appendAgentRuntimeHoursWarning`). When a soft limit exists, the tooltip states the actual soft-limit percentage computed from `soft_limit / limit`. The panel is hidden entirely when the feature is disabled, which is how the backend reports a zero-hour allocation. The usage period dates from `Feature.usage_period` render above the bar (start left, end right), matching the Agent Workspace Builds panel, so admins can tell which license period the consumption covers. The backend always attaches a period to an enabled feature; a missing or unparsable one just omits the dates row. The CODAGT-855 link to the per-user usage view is deferred: that view (F3, CODAGT-861) and the API it needs (F2, CODAGT-857) are not built yet, so there is no route to target. The link lands with F3. An enabled feature with `limit` omitted is the unlimited allocation (license claim `-1`, coder/license#49): the card shows a full neutral bar with "Limit: Unlimited" and the tooltip without threshold copy, mirroring `SeatUsageBarCard`'s unlimited state. The invalid-limits error is kept for negative limits, which can only come from a decoding bug. Storybook stories cover the green/orange/red states, the capped over-allocation bar, missing usage data, the missing usage period, the hidden state, the unlimited state, the invalid-limit error state, and each tooltip message via play interactions. The page view story verifies the panel renders above Agent Workspace Builds. Usage renders with exactly one decimal (e.g. `435.8`, `1,000.0`), derived from #27985's `actual_ms` field and floored to tenths with integer math. The same floored value drives the reached states, so the displayed number and the bar color flip at the same instant; a fraction past the allocation now trips the red state (`1,000.1 >= 1,000`), pinned by the `ReachedAllocationByFraction` story. The limit and hard cap labels stay whole because the license claims are whole hours. Stacked on #27985. closes [CODAGT-855](https://linear.app/codercom/issue/CODAGT-855/f1-runtime-hours-consumption-on-the-licenses-page).