Skip to content

Commit dddffee

Browse files
Andrew McKnightclaude
authored andcommitted
feat(gsAdmin): rework invoice-comparison summary + link receipt cells
Reshapes the admin invoice-comparison summary to lead with the parity metric operators actually scan for: the share of compared (both-sided) orgs whose per-org delta exceeds 1%. The Grid loses Legacy total, Platform total, Total delta, and Rows (each either redundant with the per-row data or duplicated by the paginator) so the headline ">1% diff" stat has room to breathe alongside the existing Unmatched and invoice-count stats; 7 cards collapses to 4. Per-row, the Legacy and Platform `$` amount cells become `Link`s to `/settings/{slug}/billing/receipts/{guid}/` whenever the row resolves to exactly one invoice on that side (the typical case), using the new `legacy_invoice_guids` / `platform_invoice_guids` fields the backend companion change adds. Multi-invoice rows fall back to plain text -- a single link can't represent N receipts and the count badge already signals the cardinality. Backend companion: getsentry feat(billing) commit, same Refs. Refs REVENG-221 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7c8f460 commit dddffee

1 file changed

Lines changed: 37 additions & 34 deletions

File tree

static/gsAdmin/views/invoiceComparison.tsx

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,21 @@ type Row = {
2929
delta_pct: number | null;
3030
legacy_amount: number | null;
3131
legacy_invoice_count: number;
32+
legacy_invoice_guids: string[];
3233
organization_id: number;
3334
organization_slug: string | null;
3435
platform_amount: number | null;
3536
platform_invoice_count: number;
37+
platform_invoice_guids: string[];
3638
status: RowStatus;
3739
};
3840

3941
type Summary = {
4042
end: string;
4143
legacy_count: number;
42-
legacy_total_cents: number;
44+
over_threshold_count: number;
45+
over_threshold_pct: number;
4346
platform_count: number;
44-
platform_total_cents: number;
4547
queried_at: string;
4648
row_count: number;
4749
rows_page: number;
@@ -87,6 +89,22 @@ function formatDollars(cents: number | null) {
8789
return `$${dollars.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
8890
}
8991

92+
function receiptUrl(orgSlug: string, guid: string) {
93+
return `/settings/${orgSlug}/billing/receipts/${guid}/`;
94+
}
95+
96+
// Render the $ amount as a link to the receipt details page when we can
97+
// pick a single invoice to point at. Multiple-invoice rows fall back to
98+
// plain text — the count badge next to the cell already signals there's
99+
// more than one, and per-invoice drill-down isn't a common workflow.
100+
function renderAmountCell(cents: number | null, guids: string[], orgSlug: string | null) {
101+
const dollars = formatDollars(cents);
102+
if (!orgSlug || guids.length !== 1) {
103+
return dollars;
104+
}
105+
return <Link to={receiptUrl(orgSlug, guids[0]!)}>{dollars}</Link>;
106+
}
107+
90108
function formatPercent(pct: number | null) {
91109
if (pct === null) {
92110
// No legacy baseline — sorts to top of the list.
@@ -405,11 +423,11 @@ export function InvoiceComparison() {
405423
<PanelHeader>Summary</PanelHeader>
406424
<PanelBody withPadding>
407425
<Grid
408-
columns="repeat(7, 1fr)"
426+
columns="repeat(4, 1fr)"
409427
gap="xl"
410428
css={css`
411429
@media (max-width: 900px) {
412-
grid-template-columns: repeat(3, 1fr);
430+
grid-template-columns: repeat(2, 1fr);
413431
}
414432
`}
415433
>
@@ -431,36 +449,13 @@ export function InvoiceComparison() {
431449
</Flex>
432450
<Flex direction="column">
433451
<Text size="sm" variant="muted">
434-
Legacy total
452+
{'>1% diff'}
435453
</Text>
436454
<Text size="lg" bold>
437-
{formatDollars(data.summary.legacy_total_cents)}
438-
</Text>
439-
</Flex>
440-
<Flex direction="column">
441-
<Text size="sm" variant="muted">
442-
Platform total
443-
</Text>
444-
<Text size="lg" bold>
445-
{formatDollars(data.summary.platform_total_cents)}
446-
</Text>
447-
</Flex>
448-
<Flex direction="column">
449-
<Text size="sm" variant="muted">
450-
Total delta
451-
</Text>
452-
<Text size="lg" bold>
453-
{formatDollars(
454-
data.summary.legacy_total_cents - data.summary.platform_total_cents
455-
)}
456-
</Text>
457-
</Flex>
458-
<Flex direction="column">
459-
<Text size="sm" variant="muted">
460-
Rows
461-
</Text>
462-
<Text size="lg" bold>
463-
{data.summary.row_count}
455+
{formatPercent(data.summary.over_threshold_pct)}
456+
<TruncatedNote size="sm" variant="muted">
457+
({data.summary.over_threshold_count} of {data.summary.row_count})
458+
</TruncatedNote>
464459
</Text>
465460
</Flex>
466461
<Flex direction="column">
@@ -522,13 +517,21 @@ export function InvoiceComparison() {
522517
)}
523518
</td>
524519
<RightCell>
525-
{formatDollars(row.legacy_amount)}{' '}
520+
{renderAmountCell(
521+
row.legacy_amount,
522+
row.legacy_invoice_guids,
523+
row.organization_slug
524+
)}{' '}
526525
<Text size="sm" variant="muted">
527526
({row.legacy_invoice_count})
528527
</Text>
529528
</RightCell>
530529
<RightCell>
531-
{formatDollars(row.platform_amount)}{' '}
530+
{renderAmountCell(
531+
row.platform_amount,
532+
row.platform_invoice_guids,
533+
row.organization_slug
534+
)}{' '}
532535
<Text size="sm" variant="muted">
533536
({row.platform_invoice_count})
534537
</Text>

0 commit comments

Comments
 (0)