Shortened the table's "Values" with k, m and bn suffixes

This commit is contained in:
bwilliams committed 2026-10-21 15:14:57 +01:00
1 parent 3bb2711276
commit 7543d85de4
3 files changed
+40 -2

No files matched your search

+8 -2
View File
@@ -9,7 +9,7 @@ import { createMemo, createSignal, For, Match, Show, Switch } from 'solid-js';
import { api } from '@/api/client'; import { api } from '@/api/client';
import { errorText } from '@/lib/errors'; import { errorText } from '@/lib/errors';
import { statusLabel } from '@/lib/filterOpportunities'; import { statusLabel } from '@/lib/filterOpportunities';
import { formatDate, formatDateTime, formatMoney, parseDate } from '@/lib/format'; import { formatDate, formatDateTime, formatMoney, formatMoneyShort, parseDate } from '@/lib/format';
import type { NoticeSite } from '@/lib/opportunities'; import type { NoticeSite } from '@/lib/opportunities';
import { latestRelease, noticeSite } from '@/lib/opportunities'; import { latestRelease, noticeSite } from '@/lib/opportunities';
import type { OpportunitySort, SortColumn } from '@/lib/sortOpportunities'; import type { OpportunitySort, SortColumn } from '@/lib/sortOpportunities';
@@ -298,7 +298,13 @@ function OpportunityRow(props: RowProps): JSX.Element {
</td> </td>
<td class={`${td} whitespace-nowrap`}>{formatDate(opportunity().start_date)}</td> <td class={`${td} whitespace-nowrap`}>{formatDate(opportunity().start_date)}</td>
<td class={`${td} whitespace-nowrap`}>{formatDate(opportunity().end_date)}</td> <td class={`${td} whitespace-nowrap`}>{formatDate(opportunity().end_date)}</td>
<td class={`${td} text-right whitespace-nowrap`}>{formatMoney(opportunity().gross_value)}</td> {/* Shortened to scan down the column; the exact amount is in the tooltip. */}
<td
class={`${td} text-right whitespace-nowrap`}
title={opportunity().gross_value > 0 ? formatMoney(opportunity().gross_value) : undefined}
>
{formatMoneyShort(opportunity().gross_value)}
</td>
<td class={td}> <td class={td}>
<MarkMenu <MarkMenu
marks={marks()} marks={marks()}
+16
View File
@@ -5,6 +5,7 @@ import {
formatDate, formatDate,
formatDateTime, formatDateTime,
formatMoney, formatMoney,
formatMoneyShort,
formatValue, formatValue,
parseDate, parseDate,
} from './format'; } from './format';
@@ -34,6 +35,21 @@ test('money is shown in whole pounds, and nothing as a dash', () => {
expect(formatMoney(-5)).toBe('—'); expect(formatMoney(-5)).toBe('—');
}); });
test.each([
{ value: 1, want: '£1' },
{ value: 500, want: '£500' },
{ value: 3563, want: '£3.6k' },
{ value: 12500, want: '£13k' },
{ value: 583333, want: '£583k' },
{ value: 1500000, want: '£1.5m' },
{ value: 9621987, want: '£9.6m' },
{ value: 36250000000, want: '£36bn' },
{ value: 0, want: '—' },
{ value: -5, want: '—' },
])('formatMoneyShort shows $value as $want', ({ value, want }) => {
expect(formatMoneyShort(value)).toBe(want);
});
test('formatCount groups thousands', () => { test('formatCount groups thousands', () => {
expect(formatCount(4854)).toBe('4,854'); expect(formatCount(4854)).toBe('4,854');
expect(formatCount(7)).toBe('7'); expect(formatCount(7)).toBe('7');
+16
View File
@@ -22,6 +22,14 @@ const moneyFormat = new Intl.NumberFormat('en-GB', {
maximumFractionDigits: 0, maximumFractionDigits: 0,
}); });
// en-GB's compact suffixes are k, m and bn; amounts under £1,000 are left
// whole.
const shortMoneyFormat = new Intl.NumberFormat('en-GB', {
style: 'currency',
currency: 'GBP',
notation: 'compact',
});
const countFormat = new Intl.NumberFormat('en-GB'); const countFormat = new Intl.NumberFormat('en-GB');
/** Treats null and Go's zero time.Time as "no date". */ /** Treats null and Go's zero time.Time as "no date". */
@@ -48,6 +56,14 @@ export function formatMoney(value: number): string {
return value > 0 ? moneyFormat.format(value) : '—'; return value > 0 ? moneyFormat.format(value) : '—';
} }
/**
* An amount in pounds shortened with a suffix, e.g. "£250k", "£1.5m" or
* "£36bn", or a dash for none. Amounts under £1,000 are shown whole.
*/
export function formatMoneyShort(value: number): string {
return value > 0 ? shortMoneyFormat.format(value) : '—';
}
/** A count for display, e.g. "4,854". */ /** A count for display, e.g. "4,854". */
export function formatCount(value: number): string { export function formatCount(value: number): string {
return countFormat.format(value); return countFormat.format(value);