fix: numbers follow the UI language, not the browser's
`n.toLocaleString()` groups in the BROWSER's locale, so an English UI in a
Hungarian browser printed "1 234 567" while a Hungarian UI in an English
browser printed "1,234,567" — the number half of the date defect fixed in
618ef812. One `formatNumber` in lib/format.ts (a per-language cached
Intl.NumberFormat, like the relative-time formatters beside it) now serves
every grouped figure: Stats, Scheduler, the channel columns and the stats
popover, VideoCard's view tooltip, the ItemCount pill, and formatTotalHours.
ReleaseNotes' `toLocaleDateString(undefined, …)` was the one DATE site the
previous sweep missed; it moves onto formatDate.
The new cases assert both languages and that the two differ, instead of
comparing against the runtime's own default: that default is Hungarian on the
dev box and English on a CI image, so a one-language assertion would pass
under the old bug on half the machines. Verified in Chromium on :5173 with the
browser forced to hu-HU and the UI in English — Stats, Scheduler and the
channel table all keep comma grouping.
This commit is contained in:
@@ -22,7 +22,7 @@ import { useLiveQuery } from "../lib/useLiveQuery";
|
||||
import { Button } from "./ui/Button";
|
||||
import { LoadingState, StateMessage } from "./ui/QueryState";
|
||||
import { useConfirm } from "./ConfirmProvider";
|
||||
import { relativeTime } from "../lib/format";
|
||||
import { formatNumber, relativeTime } from "../lib/format";
|
||||
import { notify } from "../lib/notifications";
|
||||
import Tooltip from "./ui/Tooltip";
|
||||
import { notifyActionError } from "../lib/actionErrors";
|
||||
@@ -103,9 +103,9 @@ function JobProgress({ p }: { p: SchedulerJob["progress"] }) {
|
||||
<span className="truncate">{phase}</span>
|
||||
<span className="tabular-nums shrink-0">
|
||||
{p?.total != null
|
||||
? `${p.current.toLocaleString()} / ${p.total.toLocaleString()}`
|
||||
? `${formatNumber(p.current)} / ${formatNumber(p.total)}`
|
||||
: p
|
||||
? p.current.toLocaleString()
|
||||
? formatNumber(p.current)
|
||||
: ""}
|
||||
</span>
|
||||
</div>
|
||||
@@ -291,7 +291,7 @@ function MaintenanceSettings({
|
||||
</div>
|
||||
<div className="text-2xs text-muted mt-1.5">
|
||||
{t("scheduler.maintenance.batchNote", {
|
||||
default: m.revalidate_batch_default.toLocaleString(),
|
||||
default: formatNumber(m.revalidate_batch_default),
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
@@ -540,31 +540,31 @@ export default function Scheduler() {
|
||||
icon={Database}
|
||||
label={t("scheduler.queue.recentPending")}
|
||||
hint={t("scheduler.queue.recentPendingHint")}
|
||||
value={data.queue.channels_recent_pending.toLocaleString()}
|
||||
value={formatNumber(data.queue.channels_recent_pending)}
|
||||
/>
|
||||
<Stat
|
||||
icon={Database}
|
||||
label={t("scheduler.queue.deepPending")}
|
||||
hint={t("scheduler.queue.deepPendingHint")}
|
||||
value={data.queue.channels_deep_pending.toLocaleString()}
|
||||
value={formatNumber(data.queue.channels_deep_pending)}
|
||||
/>
|
||||
<Stat
|
||||
icon={Clock}
|
||||
label={t("scheduler.queue.enrichPending")}
|
||||
hint={t("scheduler.queue.enrichPendingHint")}
|
||||
value={data.queue.videos_pending_enrich.toLocaleString()}
|
||||
value={formatNumber(data.queue.videos_pending_enrich)}
|
||||
/>
|
||||
<Stat
|
||||
icon={Clock}
|
||||
label={t("scheduler.queue.shortsPending")}
|
||||
hint={t("scheduler.queue.shortsPendingHint")}
|
||||
value={data.queue.videos_pending_shorts.toLocaleString()}
|
||||
value={formatNumber(data.queue.videos_pending_shorts)}
|
||||
/>
|
||||
<Stat
|
||||
icon={RadioTower}
|
||||
label={t("scheduler.queue.liveRefresh")}
|
||||
hint={t("scheduler.queue.liveRefreshHint")}
|
||||
value={data.queue.videos_live_refresh.toLocaleString()}
|
||||
value={formatNumber(data.queue.videos_live_refresh)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -579,15 +579,15 @@ export default function Scheduler() {
|
||||
<Gauge className="w-4 h-4 text-muted shrink-0" />
|
||||
<span>
|
||||
{t("scheduler.quotaUsed", {
|
||||
used: data.quota.used_today.toLocaleString(),
|
||||
budget: data.quota.daily_budget.toLocaleString(),
|
||||
used: formatNumber(data.quota.used_today),
|
||||
budget: formatNumber(data.quota.daily_budget),
|
||||
})}
|
||||
</span>
|
||||
<span className="flex-1" />
|
||||
<span className="text-muted text-xs">
|
||||
{t("scheduler.quotaRemaining", {
|
||||
count: data.quota.remaining_today,
|
||||
formatted: data.quota.remaining_today.toLocaleString(),
|
||||
formatted: formatNumber(data.quota.remaining_today),
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user