Skip to content

Commit f4702d1

Browse files
feat(usage): say what the breakdown is showing
The section changed scope with the page filters and never said so, and the control that changes it sits at the top of the page rather than beside the numbers it affects. The header now names the project and the period. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 649a202 commit f4702d1

4 files changed

Lines changed: 46 additions & 3 deletions

File tree

frontend/documentation/components/UsageBreakdown.stories.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,23 @@ export const BySdk: Story = {
7979
},
8080
}
8181

82+
/** The section states what it is showing, so a filter is never silently applied. */
83+
export const ScopedToAProject: Story = {
84+
args: {
85+
dimension: 'request-type',
86+
rows: [
87+
{ colour: colorChart1, key: 'flags', label: 'Flags', value: 620_000 },
88+
{
89+
colour: colorChart3,
90+
key: 'identities',
91+
label: 'Identities',
92+
value: 180_000,
93+
},
94+
],
95+
scope: 'Checkout · Last 30 days',
96+
},
97+
}
98+
8299
export const NoUsageRecorded: Story = {
83100
args: { dimension: 'request-type', rows: [] },
84101
}

frontend/web/components/pages/usage/UsageDashboardPage.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import UsageBreakdown, { useUsageBreakdown } from './components/UsageBreakdown'
1111
import UsageDashboard from './UsageDashboard'
1212
import {
1313
isBillingPeriodSelected,
14+
periodLabel,
1415
periodsFor,
1516
PeriodSelection,
1617
planHasBillingPeriod,
@@ -26,6 +27,7 @@ const UsageDashboardPage: FC<UsageDashboardPageProps> = ({
2627
organisationId,
2728
}) => {
2829
const [project, setProject] = useState<string | undefined>()
30+
const [projectName, setProjectName] = useState<string | undefined>()
2931
const selectedProjectId = project ? Number(project) : undefined
3032

3133
const {
@@ -65,6 +67,13 @@ const UsageDashboardPage: FC<UsageDashboardPageProps> = ({
6567

6668
const { setDimension, ...breakdown } = useUsageBreakdown({ data })
6769

70+
const scope = [
71+
selectedProjectId ? projectName : 'All projects',
72+
periodLabel(periods, billingPeriod),
73+
]
74+
.filter(Boolean)
75+
.join(' · ')
76+
6877
if (!organisationId) {
6978
return null
7079
}
@@ -76,7 +85,11 @@ const UsageDashboardPage: FC<UsageDashboardPageProps> = ({
7685
limit={subscriptionMeta?.max_api_calls}
7786
hasBillingPeriod={isBillingPeriodSelected(billingPeriod)}
7887
breakdown={
79-
<UsageBreakdown {...breakdown} onChangeDimension={setDimension} />
88+
<UsageBreakdown
89+
{...breakdown}
90+
onChangeDimension={setDimension}
91+
scope={scope}
92+
/>
8093
}
8194
isError={organisationFailed || usageFailed}
8295
isLoading={loadingOrganisation || loadingUsage || loadingLimit}
@@ -97,7 +110,10 @@ const UsageDashboardPage: FC<UsageDashboardPageProps> = ({
97110
inputId='usage-project'
98111
showAll
99112
organisationId={organisationId}
100-
onChange={setProject}
113+
onChange={(id: string, name: string) => {
114+
setProject(id)
115+
setProjectName(name)
116+
}}
101117
value={project}
102118
/>
103119
</div>

frontend/web/components/pages/usage/components/UsageBreakdown/UsageBreakdown.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export type UsageBreakdownProps = {
88
dimension: BreakdownDimension
99
onChangeDimension: (dimension: BreakdownDimension) => void
1010
rows: BreakdownRow[]
11+
scope?: string
1112
}
1213

1314
type DimensionOption = (typeof BREAKDOWN_DIMENSIONS)[number]
@@ -16,10 +17,14 @@ const UsageBreakdown: FC<UsageBreakdownProps> = ({
1617
dimension,
1718
onChangeDimension,
1819
rows,
20+
scope,
1921
}) => (
2022
<div className='p-4 mt-3 border border-default rounded-lg bg-surface-default'>
2123
<div className='d-flex align-items-end justify-content-between gap-3 mb-3'>
22-
<strong>Where the usage came from</strong>
24+
<div>
25+
<strong>Where the usage came from</strong>
26+
{scope && <div className='fs-captionSmall text-secondary'>{scope}</div>}
27+
</div>
2328
<div className='usage-breakdown__dimension'>
2429
<FieldLabel htmlFor='usage-breakdown-dimension'>
2530
Break down by

frontend/web/components/pages/usage/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,10 @@ export const resolvePeriod = (
2626
export const isBillingPeriodSelected = (period: BillingPeriod): boolean =>
2727
period === 'current_billing_period' || period === 'previous_billing_period'
2828

29+
export const periodLabel = (
30+
periods: PeriodOption[],
31+
period: BillingPeriod,
32+
): string => periods.find((option) => option.value === period)?.label ?? ''
33+
2934
export const periodsFor = (billingPeriodAvailable: boolean): PeriodOption[] =>
3035
billingPeriodAvailable ? periodOptions : rollingPeriodOptions

0 commit comments

Comments
 (0)