feat(telemetry): generic event aggregates and usage range presets

- rollups emit event.count (dim name) and event.detail.count (dim name|detail
  from props.source/emoji/tournament)
- usage screen: events section with tap-through breakdown; 7d/30d/180d/custom
  date-range presets
This commit is contained in:
2026-08-26 22:53:58 -07:00
parent cb16d9757e
commit 8171354e2a
8 changed files with 370 additions and 89 deletions
@@ -11,6 +11,8 @@ import {
} from "@mantine/core";
import { ListSkeleton, StatTileSkeleton } from "@/components/skeletons";
import { useRollupRange } from "../queries";
import type { RollupRow } from "../types";
import { DatePickerInput } from "@mantine/dates";
import { fillDailySeries, lastNDays, latestValue, listDays, sumByDim } from "../range";
import { BarList, Sparkline, StatTile } from "./charts";
import { DetailSheet } from "./shared";
@@ -25,6 +27,8 @@ export const USAGE_METRICS = [
"server_fn.count",
"client_error.count",
"vital.p75",
"event.count",
"event.detail.count",
];
const TOP_LIST_SIZE = 8;
@@ -122,10 +126,37 @@ const FnDurationDetail = ({ fn, from, to }: { fn: string; from: string; to: stri
);
};
const EventBreakdown = ({ name, rows }: { name: string; rows: RollupRow[] }) => {
const items = useMemo(() => {
const totals = new Map<string, number>();
const prefix = `${name}|`;
for (const row of rows) {
if (row.metric !== "event.detail.count" || !row.dim.startsWith(prefix)) continue;
const detail = row.dim.slice(prefix.length);
totals.set(detail, (totals.get(detail) ?? 0) + row.value);
}
return [...totals.entries()]
.sort((a, b) => b[1] - a[1])
.map(([label, value]) => ({ label, value }));
}, [name, rows]);
if (items.length === 0) {
return (
<Text size="sm" c="dimmed">
<Trans>No breakdown recorded</Trans>
</Text>
);
}
return <BarList items={items} />;
};
const UsageSections = ({ from, to }: { from: string; to: string }) => {
const { t, i18n } = useLingui();
const [selectedFn, setSelectedFn] = useState<string | null>(null);
const { isOpen: fnDetailOpened, open: openFnDetail, close: closeFnDetail } = useSheet();
const [selectedEvent, setSelectedEvent] = useState<string | null>(null);
const { isOpen: eventDetailOpened, open: openEventDetail, close: closeEventDetail } = useSheet();
const { data: rows } = useRollupRange({ metrics: USAGE_METRICS, from, to });
@@ -142,6 +173,10 @@ const UsageSections = ({ from, to }: { from: string; to: string }) => {
setSelectedFn(dim);
openFnDetail();
});
const eventItems = topItems(sumByDim(rows, "event.count"), (dim) => {
setSelectedEvent(dim);
openEventDetail();
});
const vitals = (["LCP", "INP", "CLS"] as VitalName[]).map((name) => ({
name,
@@ -186,6 +221,26 @@ const UsageSections = ({ from, to }: { from: string; to: string }) => {
<Divider />
<Stack gap="sm">
<Title order={4}>
<Trans>Events</Trans>
</Title>
{eventItems.length > 0 ? (
<Stack gap="xs">
<Text size="xs" c="dimmed">
<Trans>Top interactions, tap for breakdown</Trans>
</Text>
<BarList items={eventItems} />
</Stack>
) : (
<Text size="sm" c="dimmed">
<Trans>No events recorded in this range</Trans>
</Text>
)}
</Stack>
<Divider />
<Stack gap="sm">
<Title order={4}>
<Trans>Server functions</Trans>
@@ -230,6 +285,25 @@ const UsageSections = ({ from, to }: { from: string; to: string }) => {
</SimpleGrid>
</Stack>
<DetailSheet
title={selectedEvent ?? t`Event`}
opened={eventDetailOpened}
onClose={() => {
setSelectedEvent(null);
closeEventDetail();
}}
fields={
selectedEvent
? [
{
label: <Trans>Breakdown</Trans>,
value: <EventBreakdown name={selectedEvent} rows={rows} />,
},
]
: []
}
/>
<DetailSheet
title={selectedFn ?? t`Function`}
opened={fnDetailOpened}
@@ -251,36 +325,61 @@ const UsageSections = ({ from, to }: { from: string; to: string }) => {
export const UsageScreen = () => {
const { t } = useLingui();
const [rangeDays, setRangeDays] = useState<"7" | "30">("7");
const range = useMemo(() => lastNDays(Number(rangeDays)), [rangeDays]);
const [preset, setPreset] = useState<"7" | "30" | "180" | "custom">("7");
const [customRange, setCustomRange] = useState<[string | null, string | null]>([null, null]);
const range = useMemo(() => {
if (preset !== "custom") return lastNDays(Number(preset));
const [start, end] = customRange;
if (!start || !end) return null;
return { from: start, to: end };
}, [preset, customRange]);
return (
<Stack gap="md" px="md" pb="md">
<SegmentedControl
value={rangeDays}
onChange={(value) => setRangeDays(value as "7" | "30")}
value={preset}
onChange={(value) => setPreset(value as typeof preset)}
data={[
{ value: "7", label: t`7d` },
{ value: "30", label: t`30d` },
{ value: "180", label: t`180d` },
{ value: "custom", label: t`Custom` },
]}
fullWidth
/>
<Suspense
fallback={
<Stack gap="lg">
<StatTileSkeleton align="row" />
<SimpleGrid cols={3} spacing="sm">
<StatTileSkeleton />
<StatTileSkeleton />
<StatTileSkeleton />
</SimpleGrid>
<ListSkeleton rows={6} withTrailing="text" />
</Stack>
}
>
<UsageSections from={range.from} to={range.to} />
</Suspense>
{preset === "custom" && (
<DatePickerInput
type="range"
value={customRange}
onChange={setCustomRange}
maxDate={new Date()}
placeholder={t`Pick a date range`}
/>
)}
{range ? (
<Suspense
fallback={
<Stack gap="lg">
<StatTileSkeleton align="row" />
<SimpleGrid cols={3} spacing="sm">
<StatTileSkeleton />
<StatTileSkeleton />
<StatTileSkeleton />
</SimpleGrid>
<ListSkeleton rows={6} withTrailing="text" />
</Stack>
}
>
<UsageSections from={range.from} to={range.to} />
</Suspense>
) : (
<Text size="sm" c="dimmed" ta="center" py="xl">
<Trans>Pick a date range to see usage</Trans>
</Text>
)}
</Stack>
);
};
+1 -1
View File
@@ -134,7 +134,7 @@ export const resolveClientErrorGroup = createServerFn({ method: "POST" })
);
const rollupRangeSchema = z.object({
metrics: z.array(z.string()).min(1).max(8),
metrics: z.array(z.string()).min(1).max(12),
from: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
to: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
dim: z.string().optional(),
+22
View File
@@ -14,6 +14,7 @@ export interface ClientEventRow {
session_id?: string;
route_id?: string;
value?: number;
props?: { source?: string; emoji?: string; tournament?: string } | null;
}
export interface ClientErrorRow {
@@ -64,6 +65,8 @@ export interface ClientEventAccumulator {
sessions: Set<string>;
pageViewsByRoute: Map<string, number>;
vitals: Map<string, number[]>;
eventCounts: Map<string, number>;
eventDetails: Map<string, number>;
}
export const newClientEventAccumulator = (): ClientEventAccumulator => ({
@@ -71,8 +74,13 @@ export const newClientEventAccumulator = (): ClientEventAccumulator => ({
sessions: new Set(),
pageViewsByRoute: new Map(),
vitals: new Map(),
eventCounts: new Map(),
eventDetails: new Map(),
});
const eventDetail = (row: ClientEventRow): string | undefined =>
row.props?.source ?? row.props?.emoji ?? row.props?.tournament;
export const accumulateClientEvents = (acc: ClientEventAccumulator, rows: ClientEventRow[]) => {
for (const row of rows) {
if (row.player) acc.players.add(row.player);
@@ -86,6 +94,13 @@ export const accumulateClientEvents = (acc: ClientEventAccumulator, rows: Client
const values = acc.vitals.get(metric) ?? [];
values.push(row.value);
acc.vitals.set(metric, values);
} else {
acc.eventCounts.set(row.name, (acc.eventCounts.get(row.name) ?? 0) + 1);
const detail = eventDetail(row);
if (detail) {
const key = `${row.name}|${detail}`;
acc.eventDetails.set(key, (acc.eventDetails.get(key) ?? 0) + 1);
}
}
}
};
@@ -157,6 +172,13 @@ export const buildDayRollups = (
push("page_view.count", "", totalPageViews);
push("page_view.sessions", "", clientEvents.sessions.size);
for (const [name, count] of clientEvents.eventCounts) {
push("event.count", name, count);
}
for (const [key, count] of clientEvents.eventDetails) {
push("event.detail.count", key, count);
}
push("client_error.count", "", clientErrors.total);
for (const [group, count] of clientErrors.byGroup) {
push("client_error.count", group, count);
+1 -1
View File
@@ -59,7 +59,7 @@ export const runRollups = async (
);
await pbAdmin.pageCollection<ClientEventRow>(
"client_events",
{ filter: dayFilter(dateStr), fields: "name,player,session_id,route_id,value,created" },
{ filter: dayFilter(dateStr), fields: "name,player,session_id,route_id,value,props,created" },
(rows) => accumulateClientEvents(clientEvents, rows)
);
await pbAdmin.pageCollection<ClientErrorRow>(
+57 -17
View File
@@ -346,6 +346,10 @@ msgstr "✓ Als Free Agent angemeldet"
msgid "1. Correct champion pick"
msgstr "1. Richtiger Meister-Tipp"
#: src/features/telemetry/components/usage-screen.tsx:346
msgid "180d"
msgstr "180T"
#: src/features/teams/components/team-form/duration-picker.tsx:22
msgid "1m"
msgstr "1 min"
@@ -362,7 +366,7 @@ msgstr "2. Frühere Abgabe"
msgid "2nd place"
msgstr "2. Platz"
#: src/features/telemetry/components/usage-screen.tsx:264
#: src/features/telemetry/components/usage-screen.tsx:345
msgid "30d"
msgstr "30 T"
@@ -378,7 +382,7 @@ msgstr "3. Platz"
msgid "5s"
msgstr "5 s"
#: src/features/telemetry/components/usage-screen.tsx:263
#: src/features/telemetry/components/usage-screen.tsx:344
msgid "7d"
msgstr "7 T"
@@ -649,6 +653,10 @@ msgstr "Turnierbaum-Vorschau"
msgid "Bracket Reset"
msgstr "Bracket-Reset"
#: src/features/telemetry/components/usage-screen.tsx:299
msgid "Breakdown"
msgstr "Aufschlüsselung"
#: src/themes/brutal/manifest.ts:6
msgid "Brutal"
msgstr "Brutal"
@@ -720,7 +728,7 @@ msgstr "Ausgewählten Spieler entfernen"
msgid "Client error spike"
msgstr "Anstieg von Client-Fehlern"
#: src/features/telemetry/components/usage-screen.tsx:208
#: src/features/telemetry/components/usage-screen.tsx:263
msgid "Client errors"
msgstr "Client-Fehler"
@@ -878,11 +886,15 @@ msgstr "Becher kassiert"
msgid "Cups Made"
msgstr "Becher erzielt"
#: src/features/telemetry/components/usage-screen.tsx:347
msgid "Custom"
msgstr "Benutzerdefiniert"
#: src/features/teams/components/team-form/color-picker.tsx:63
msgid "Custom Hex Code"
msgstr "Benutzerdefinierter Hex-Code"
#: src/features/telemetry/components/usage-screen.tsx:163
#: src/features/telemetry/components/usage-screen.tsx:198
msgid "Daily active players"
msgstr "Täglich aktive Spieler"
@@ -941,7 +953,7 @@ msgstr "Nachfolgende Matches wurden zurückgesetzt, da sich durch die Korrektur
msgid "Duration"
msgstr "Dauer"
#: src/features/telemetry/components/usage-screen.tsx:241
#: src/features/telemetry/components/usage-screen.tsx:315
msgid "Duration p50 / p95"
msgstr "Dauer p50 / p95"
@@ -1003,7 +1015,7 @@ msgstr "Enddatum (optional)"
msgid "End Match"
msgstr "Match beenden"
#: src/features/telemetry/components/usage-screen.tsx:160
#: src/features/telemetry/components/usage-screen.tsx:195
msgid "Engagement"
msgstr "Engagement"
@@ -1107,10 +1119,18 @@ msgid "Error: {errorMessage}"
msgstr "Fehler: {errorMessage}"
#: src/app/routes/_authed/admin/telemetry.tsx:57
#: src/features/telemetry/components/usage-screen.tsx:205
#: src/features/telemetry/components/usage-screen.tsx:260
msgid "Errors"
msgstr "Fehler"
#: src/features/telemetry/components/usage-screen.tsx:289
msgid "Event"
msgstr "Ereignis"
#: src/features/telemetry/components/usage-screen.tsx:226
msgid "Events"
msgstr "Ereignisse"
#: src/features/tournaments/components/group-stage-view.tsx:368
msgid "Expand standings"
msgstr "Tabelle erweitern"
@@ -1236,7 +1256,7 @@ msgstr "Free-Agent-Anmeldung"
msgid "Free Agents"
msgstr "Free Agents"
#: src/features/telemetry/components/usage-screen.tsx:234
#: src/features/telemetry/components/usage-screen.tsx:308
msgid "Function"
msgstr "Funktion"
@@ -1618,7 +1638,7 @@ msgstr "Matchup"
msgid "Matchup details"
msgstr "Matchup-Details"
#: src/features/telemetry/components/usage-screen.tsx:174
#: src/features/telemetry/components/usage-screen.tsx:209
msgid "MAU"
msgstr "MAU"
@@ -1731,10 +1751,18 @@ msgstr "Keine Aktivitäten gefunden"
msgid "No Badges Available"
msgstr "Keine Abzeichen verfügbar"
#: src/features/telemetry/components/usage-screen.tsx:146
msgid "No breakdown recorded"
msgstr "Keine Aufschlüsselung vorhanden"
#: src/features/spotify/components/spotify-sheet.tsx:154
msgid "No devices found."
msgstr "Keine Geräte gefunden."
#: src/features/telemetry/components/usage-screen.tsx:237
msgid "No events recorded in this range"
msgstr "Keine Ereignisse in diesem Zeitraum"
#: src/features/tournaments/components/group-stage-view.tsx:294
msgid "No groups have been created yet"
msgstr "Es wurden noch keine Gruppen erstellt"
@@ -1922,15 +1950,15 @@ msgstr "Übersicht"
msgid "owo"
msgstr "owo"
#: src/features/telemetry/components/usage-screen.tsx:101
#: src/features/telemetry/components/usage-screen.tsx:105
msgid "p50"
msgstr "p50"
#: src/features/telemetry/components/usage-screen.tsx:117
#: src/features/telemetry/components/usage-screen.tsx:121
msgid "p95"
msgstr "p95"
#: src/features/telemetry/components/usage-screen.tsx:181
#: src/features/telemetry/components/usage-screen.tsx:216
msgid "Page views by route"
msgstr "Seitenaufrufe nach Route"
@@ -1964,6 +1992,14 @@ msgstr "Telefonnummer ist erforderlich"
msgid "Phone number must be 10 digits"
msgstr "Telefonnummer muss 10 Ziffern haben"
#: src/features/telemetry/components/usage-screen.tsx:358
msgid "Pick a date range"
msgstr "Zeitraum auswählen"
#: src/features/telemetry/components/usage-screen.tsx:380
msgid "Pick a date range to see usage"
msgstr "Zeitraum auswählen, um die Nutzung zu sehen"
#: src/features/predictions/components/matchup-sheet.tsx:49
msgid "Pick the earlier matches first — these teams aren't decided yet."
msgstr "Wähle zuerst die früheren Spiele — diese Teams stehen noch nicht fest."
@@ -2322,7 +2358,7 @@ msgstr "Serie steht unentschieden"
msgid "Server function failing"
msgstr "Serverfunktion schlägt fehl"
#: src/features/telemetry/components/usage-screen.tsx:191
#: src/features/telemetry/components/usage-screen.tsx:246
msgid "Server functions"
msgstr "Serverfunktionen"
@@ -2331,7 +2367,7 @@ msgid "serverFn name"
msgstr "serverFn-Name"
#: src/app/routes/_authed/admin/telemetry.tsx:54
#: src/features/telemetry/components/usage-screen.tsx:177
#: src/features/telemetry/components/usage-screen.tsx:212
msgid "Sessions"
msgstr "Sitzungen"
@@ -2667,10 +2703,14 @@ msgstr "Die besten {0, plural, one {# Team} other {# Teams}} aus jeder Gruppe ko
msgid "Top {n} advance"
msgstr "Top {n} kommen weiter"
#: src/features/telemetry/components/usage-screen.tsx:195
#: src/features/telemetry/components/usage-screen.tsx:250
msgid "Top functions by call count"
msgstr "Top-Funktionen nach Aufrufanzahl"
#: src/features/telemetry/components/usage-screen.tsx:231
msgid "Top interactions, tap for breakdown"
msgstr "Top-Interaktionen, tippen für Details"
#: src/features/matches/components/team-head-to-head-sheet.tsx:158
#: src/features/players/components/player-head-to-head-sheet.tsx:193
msgid "Total Cups"
@@ -2826,7 +2866,7 @@ msgstr "Tipps ansehen"
msgid "Viewport"
msgstr "Viewport"
#: src/features/telemetry/components/usage-screen.tsx:219
#: src/features/telemetry/components/usage-screen.tsx:274
msgid "Vitals"
msgstr "Vitals"
@@ -2865,7 +2905,7 @@ msgstr "Walkout-Segment ({segmentDuration}s)"
msgid "Walkout Song"
msgstr "Walkout-Song"
#: src/features/telemetry/components/usage-screen.tsx:170
#: src/features/telemetry/components/usage-screen.tsx:205
msgid "WAU"
msgstr "WAU"
+57 -17
View File
@@ -346,6 +346,10 @@ msgstr "✓ Enrolled as Free Agent"
msgid "1. Correct champion pick"
msgstr "1. Correct champion pick"
#: src/features/telemetry/components/usage-screen.tsx:346
msgid "180d"
msgstr "180d"
#: src/features/teams/components/team-form/duration-picker.tsx:22
msgid "1m"
msgstr "1m"
@@ -362,7 +366,7 @@ msgstr "2. Earlier submission"
msgid "2nd place"
msgstr "2nd place"
#: src/features/telemetry/components/usage-screen.tsx:264
#: src/features/telemetry/components/usage-screen.tsx:345
msgid "30d"
msgstr "30d"
@@ -378,7 +382,7 @@ msgstr "3rd place"
msgid "5s"
msgstr "5s"
#: src/features/telemetry/components/usage-screen.tsx:263
#: src/features/telemetry/components/usage-screen.tsx:344
msgid "7d"
msgstr "7d"
@@ -649,6 +653,10 @@ msgstr "Bracket Preview"
msgid "Bracket Reset"
msgstr "Bracket Reset"
#: src/features/telemetry/components/usage-screen.tsx:299
msgid "Breakdown"
msgstr "Breakdown"
#: src/themes/brutal/manifest.ts:6
msgid "Brutal"
msgstr "Brutal"
@@ -720,7 +728,7 @@ msgstr "Clear selected player"
msgid "Client error spike"
msgstr "Client error spike"
#: src/features/telemetry/components/usage-screen.tsx:208
#: src/features/telemetry/components/usage-screen.tsx:263
msgid "Client errors"
msgstr "Client errors"
@@ -878,11 +886,15 @@ msgstr "Cups Against"
msgid "Cups Made"
msgstr "Cups Made"
#: src/features/telemetry/components/usage-screen.tsx:347
msgid "Custom"
msgstr "Custom"
#: src/features/teams/components/team-form/color-picker.tsx:63
msgid "Custom Hex Code"
msgstr "Custom Hex Code"
#: src/features/telemetry/components/usage-screen.tsx:163
#: src/features/telemetry/components/usage-screen.tsx:198
msgid "Daily active players"
msgstr "Daily active players"
@@ -941,7 +953,7 @@ msgstr "Downstream matches were reset because the correction changed who advance
msgid "Duration"
msgstr "Duration"
#: src/features/telemetry/components/usage-screen.tsx:241
#: src/features/telemetry/components/usage-screen.tsx:315
msgid "Duration p50 / p95"
msgstr "Duration p50 / p95"
@@ -1003,7 +1015,7 @@ msgstr "End Date (Optional)"
msgid "End Match"
msgstr "End Match"
#: src/features/telemetry/components/usage-screen.tsx:160
#: src/features/telemetry/components/usage-screen.tsx:195
msgid "Engagement"
msgstr "Engagement"
@@ -1107,10 +1119,18 @@ msgid "Error: {errorMessage}"
msgstr "Error: {errorMessage}"
#: src/app/routes/_authed/admin/telemetry.tsx:57
#: src/features/telemetry/components/usage-screen.tsx:205
#: src/features/telemetry/components/usage-screen.tsx:260
msgid "Errors"
msgstr "Errors"
#: src/features/telemetry/components/usage-screen.tsx:289
msgid "Event"
msgstr "Event"
#: src/features/telemetry/components/usage-screen.tsx:226
msgid "Events"
msgstr "Events"
#: src/features/tournaments/components/group-stage-view.tsx:368
msgid "Expand standings"
msgstr "Expand standings"
@@ -1236,7 +1256,7 @@ msgstr "Free Agent Enrollment"
msgid "Free Agents"
msgstr "Free Agents"
#: src/features/telemetry/components/usage-screen.tsx:234
#: src/features/telemetry/components/usage-screen.tsx:308
msgid "Function"
msgstr "Function"
@@ -1618,7 +1638,7 @@ msgstr "Matchup"
msgid "Matchup details"
msgstr "Matchup details"
#: src/features/telemetry/components/usage-screen.tsx:174
#: src/features/telemetry/components/usage-screen.tsx:209
msgid "MAU"
msgstr "MAU"
@@ -1731,10 +1751,18 @@ msgstr "No Activities Found"
msgid "No Badges Available"
msgstr "No Badges Available"
#: src/features/telemetry/components/usage-screen.tsx:146
msgid "No breakdown recorded"
msgstr "No breakdown recorded"
#: src/features/spotify/components/spotify-sheet.tsx:154
msgid "No devices found."
msgstr "No devices found."
#: src/features/telemetry/components/usage-screen.tsx:237
msgid "No events recorded in this range"
msgstr "No events recorded in this range"
#: src/features/tournaments/components/group-stage-view.tsx:294
msgid "No groups have been created yet"
msgstr "No groups have been created yet"
@@ -1922,15 +1950,15 @@ msgstr "Overview"
msgid "owo"
msgstr "owo"
#: src/features/telemetry/components/usage-screen.tsx:101
#: src/features/telemetry/components/usage-screen.tsx:105
msgid "p50"
msgstr "p50"
#: src/features/telemetry/components/usage-screen.tsx:117
#: src/features/telemetry/components/usage-screen.tsx:121
msgid "p95"
msgstr "p95"
#: src/features/telemetry/components/usage-screen.tsx:181
#: src/features/telemetry/components/usage-screen.tsx:216
msgid "Page views by route"
msgstr "Page views by route"
@@ -1964,6 +1992,14 @@ msgstr "Phone number is required"
msgid "Phone number must be 10 digits"
msgstr "Phone number must be 10 digits"
#: src/features/telemetry/components/usage-screen.tsx:358
msgid "Pick a date range"
msgstr "Pick a date range"
#: src/features/telemetry/components/usage-screen.tsx:380
msgid "Pick a date range to see usage"
msgstr "Pick a date range to see usage"
#: src/features/predictions/components/matchup-sheet.tsx:49
msgid "Pick the earlier matches first — these teams aren't decided yet."
msgstr "Pick the earlier matches first — these teams aren't decided yet."
@@ -2322,7 +2358,7 @@ msgstr "Series is tied"
msgid "Server function failing"
msgstr "Server function failing"
#: src/features/telemetry/components/usage-screen.tsx:191
#: src/features/telemetry/components/usage-screen.tsx:246
msgid "Server functions"
msgstr "Server functions"
@@ -2331,7 +2367,7 @@ msgid "serverFn name"
msgstr "serverFn name"
#: src/app/routes/_authed/admin/telemetry.tsx:54
#: src/features/telemetry/components/usage-screen.tsx:177
#: src/features/telemetry/components/usage-screen.tsx:212
msgid "Sessions"
msgstr "Sessions"
@@ -2667,10 +2703,14 @@ msgstr "Top {0, plural, one {# team} other {# teams}} from each group will advan
msgid "Top {n} advance"
msgstr "Top {n} advance"
#: src/features/telemetry/components/usage-screen.tsx:195
#: src/features/telemetry/components/usage-screen.tsx:250
msgid "Top functions by call count"
msgstr "Top functions by call count"
#: src/features/telemetry/components/usage-screen.tsx:231
msgid "Top interactions, tap for breakdown"
msgstr "Top interactions, tap for breakdown"
#: src/features/matches/components/team-head-to-head-sheet.tsx:158
#: src/features/players/components/player-head-to-head-sheet.tsx:193
msgid "Total Cups"
@@ -2826,7 +2866,7 @@ msgstr "View Predictions"
msgid "Viewport"
msgstr "Viewport"
#: src/features/telemetry/components/usage-screen.tsx:219
#: src/features/telemetry/components/usage-screen.tsx:274
msgid "Vitals"
msgstr "Vitals"
@@ -2865,7 +2905,7 @@ msgstr "Walkout Segment ({segmentDuration}s)"
msgid "Walkout Song"
msgstr "Walkout Song"
#: src/features/telemetry/components/usage-screen.tsx:170
#: src/features/telemetry/components/usage-screen.tsx:205
msgid "WAU"
msgstr "WAU"
+57 -17
View File
@@ -346,6 +346,10 @@ msgstr "✓ Inscrito como agente libre"
msgid "1. Correct champion pick"
msgstr "1. Acierto del campeón"
#: src/features/telemetry/components/usage-screen.tsx:346
msgid "180d"
msgstr "180d"
#: src/features/teams/components/team-form/duration-picker.tsx:22
msgid "1m"
msgstr "1m"
@@ -362,7 +366,7 @@ msgstr "2. Envío más temprano"
msgid "2nd place"
msgstr "2do lugar"
#: src/features/telemetry/components/usage-screen.tsx:264
#: src/features/telemetry/components/usage-screen.tsx:345
msgid "30d"
msgstr "30d"
@@ -378,7 +382,7 @@ msgstr "3er lugar"
msgid "5s"
msgstr "5s"
#: src/features/telemetry/components/usage-screen.tsx:263
#: src/features/telemetry/components/usage-screen.tsx:344
msgid "7d"
msgstr "7d"
@@ -649,6 +653,10 @@ msgstr "Vista previa del bracket"
msgid "Bracket Reset"
msgstr "Reinicio del bracket"
#: src/features/telemetry/components/usage-screen.tsx:299
msgid "Breakdown"
msgstr "Desglose"
#: src/themes/brutal/manifest.ts:6
msgid "Brutal"
msgstr "Brutal"
@@ -720,7 +728,7 @@ msgstr "Quitar jugador seleccionado"
msgid "Client error spike"
msgstr "Aumento de errores de cliente"
#: src/features/telemetry/components/usage-screen.tsx:208
#: src/features/telemetry/components/usage-screen.tsx:263
msgid "Client errors"
msgstr "Errores de cliente"
@@ -878,11 +886,15 @@ msgstr "Vasos en contra"
msgid "Cups Made"
msgstr "Vasos anotados"
#: src/features/telemetry/components/usage-screen.tsx:347
msgid "Custom"
msgstr "Personalizado"
#: src/features/teams/components/team-form/color-picker.tsx:63
msgid "Custom Hex Code"
msgstr "Código hex personalizado"
#: src/features/telemetry/components/usage-screen.tsx:163
#: src/features/telemetry/components/usage-screen.tsx:198
msgid "Daily active players"
msgstr "Jugadores activos diarios"
@@ -941,7 +953,7 @@ msgstr "Los partidos posteriores se reiniciaron porque la corrección cambió qu
msgid "Duration"
msgstr "Duración"
#: src/features/telemetry/components/usage-screen.tsx:241
#: src/features/telemetry/components/usage-screen.tsx:315
msgid "Duration p50 / p95"
msgstr "Duración p50 / p95"
@@ -1003,7 +1015,7 @@ msgstr "Fecha de fin (opcional)"
msgid "End Match"
msgstr "Terminar partido"
#: src/features/telemetry/components/usage-screen.tsx:160
#: src/features/telemetry/components/usage-screen.tsx:195
msgid "Engagement"
msgstr "Interacción"
@@ -1107,10 +1119,18 @@ msgid "Error: {errorMessage}"
msgstr "Error: {errorMessage}"
#: src/app/routes/_authed/admin/telemetry.tsx:57
#: src/features/telemetry/components/usage-screen.tsx:205
#: src/features/telemetry/components/usage-screen.tsx:260
msgid "Errors"
msgstr "Errores"
#: src/features/telemetry/components/usage-screen.tsx:289
msgid "Event"
msgstr "Evento"
#: src/features/telemetry/components/usage-screen.tsx:226
msgid "Events"
msgstr "Eventos"
#: src/features/tournaments/components/group-stage-view.tsx:368
msgid "Expand standings"
msgstr "Expandir tabla de posiciones"
@@ -1236,7 +1256,7 @@ msgstr "Inscripción de agente libre"
msgid "Free Agents"
msgstr "Agentes libres"
#: src/features/telemetry/components/usage-screen.tsx:234
#: src/features/telemetry/components/usage-screen.tsx:308
msgid "Function"
msgstr "Función"
@@ -1618,7 +1638,7 @@ msgstr "Enfrentamiento"
msgid "Matchup details"
msgstr "Detalles del enfrentamiento"
#: src/features/telemetry/components/usage-screen.tsx:174
#: src/features/telemetry/components/usage-screen.tsx:209
msgid "MAU"
msgstr "MAU"
@@ -1731,10 +1751,18 @@ msgstr "No se encontraron actividades"
msgid "No Badges Available"
msgstr "No hay insignias disponibles"
#: src/features/telemetry/components/usage-screen.tsx:146
msgid "No breakdown recorded"
msgstr "Sin desglose registrado"
#: src/features/spotify/components/spotify-sheet.tsx:154
msgid "No devices found."
msgstr "No se encontraron dispositivos."
#: src/features/telemetry/components/usage-screen.tsx:237
msgid "No events recorded in this range"
msgstr "No hay eventos en este rango"
#: src/features/tournaments/components/group-stage-view.tsx:294
msgid "No groups have been created yet"
msgstr "Aún no se han creado grupos"
@@ -1922,15 +1950,15 @@ msgstr "Resumen"
msgid "owo"
msgstr "owo"
#: src/features/telemetry/components/usage-screen.tsx:101
#: src/features/telemetry/components/usage-screen.tsx:105
msgid "p50"
msgstr "p50"
#: src/features/telemetry/components/usage-screen.tsx:117
#: src/features/telemetry/components/usage-screen.tsx:121
msgid "p95"
msgstr "p95"
#: src/features/telemetry/components/usage-screen.tsx:181
#: src/features/telemetry/components/usage-screen.tsx:216
msgid "Page views by route"
msgstr "Vistas de página por ruta"
@@ -1964,6 +1992,14 @@ msgstr "El número de teléfono es obligatorio"
msgid "Phone number must be 10 digits"
msgstr "El número de teléfono debe tener 10 dígitos"
#: src/features/telemetry/components/usage-screen.tsx:358
msgid "Pick a date range"
msgstr "Elige un rango de fechas"
#: src/features/telemetry/components/usage-screen.tsx:380
msgid "Pick a date range to see usage"
msgstr "Elige un rango de fechas para ver el uso"
#: src/features/predictions/components/matchup-sheet.tsx:49
msgid "Pick the earlier matches first — these teams aren't decided yet."
msgstr "Elige primero los partidos anteriores — estos equipos todavía no están decididos."
@@ -2322,7 +2358,7 @@ msgstr "La serie está empatada"
msgid "Server function failing"
msgstr "Función del servidor fallando"
#: src/features/telemetry/components/usage-screen.tsx:191
#: src/features/telemetry/components/usage-screen.tsx:246
msgid "Server functions"
msgstr "Funciones del servidor"
@@ -2331,7 +2367,7 @@ msgid "serverFn name"
msgstr "nombre de serverFn"
#: src/app/routes/_authed/admin/telemetry.tsx:54
#: src/features/telemetry/components/usage-screen.tsx:177
#: src/features/telemetry/components/usage-screen.tsx:212
msgid "Sessions"
msgstr "Sesiones"
@@ -2667,10 +2703,14 @@ msgstr "{0, plural, one {El mejor equipo de cada grupo avanzará} other {Los mej
msgid "Top {n} advance"
msgstr "Los mejores {n} avanzan"
#: src/features/telemetry/components/usage-screen.tsx:195
#: src/features/telemetry/components/usage-screen.tsx:250
msgid "Top functions by call count"
msgstr "Funciones principales por cantidad de llamadas"
#: src/features/telemetry/components/usage-screen.tsx:231
msgid "Top interactions, tap for breakdown"
msgstr "Interacciones principales, toca para ver el desglose"
#: src/features/matches/components/team-head-to-head-sheet.tsx:158
#: src/features/players/components/player-head-to-head-sheet.tsx:193
msgid "Total Cups"
@@ -2826,7 +2866,7 @@ msgstr "Ver predicciones"
msgid "Viewport"
msgstr "Viewport"
#: src/features/telemetry/components/usage-screen.tsx:219
#: src/features/telemetry/components/usage-screen.tsx:274
msgid "Vitals"
msgstr "Vitales"
@@ -2865,7 +2905,7 @@ msgstr "Segmento de entrada ({segmentDuration}s)"
msgid "Walkout Song"
msgstr "Canción de entrada"
#: src/features/telemetry/components/usage-screen.tsx:170
#: src/features/telemetry/components/usage-screen.tsx:205
msgid "WAU"
msgstr "WAU"
+57 -17
View File
@@ -346,6 +346,10 @@ msgstr "✓ フリーエージェントとして登録済み"
msgid "1. Correct champion pick"
msgstr "1. 優勝チーム予想が的中"
#: src/features/telemetry/components/usage-screen.tsx:346
msgid "180d"
msgstr "180日"
#: src/features/teams/components/team-form/duration-picker.tsx:22
msgid "1m"
msgstr "1分"
@@ -362,7 +366,7 @@ msgstr "2. 早い提出"
msgid "2nd place"
msgstr "2位"
#: src/features/telemetry/components/usage-screen.tsx:264
#: src/features/telemetry/components/usage-screen.tsx:345
msgid "30d"
msgstr "30日"
@@ -378,7 +382,7 @@ msgstr "3位"
msgid "5s"
msgstr "5秒"
#: src/features/telemetry/components/usage-screen.tsx:263
#: src/features/telemetry/components/usage-screen.tsx:344
msgid "7d"
msgstr "7日"
@@ -649,6 +653,10 @@ msgstr "ブラケットプレビュー"
msgid "Bracket Reset"
msgstr "ブラケットリセット"
#: src/features/telemetry/components/usage-screen.tsx:299
msgid "Breakdown"
msgstr "内訳"
#: src/themes/brutal/manifest.ts:6
msgid "Brutal"
msgstr "ブルータル"
@@ -720,7 +728,7 @@ msgstr "選択したプレイヤーを解除"
msgid "Client error spike"
msgstr "クライアントエラー急増"
#: src/features/telemetry/components/usage-screen.tsx:208
#: src/features/telemetry/components/usage-screen.tsx:263
msgid "Client errors"
msgstr "クライアントエラー"
@@ -878,11 +886,15 @@ msgstr "失カップ"
msgid "Cups Made"
msgstr "決めたカップ"
#: src/features/telemetry/components/usage-screen.tsx:347
msgid "Custom"
msgstr "カスタム"
#: src/features/teams/components/team-form/color-picker.tsx:63
msgid "Custom Hex Code"
msgstr "カスタムHEXコード"
#: src/features/telemetry/components/usage-screen.tsx:163
#: src/features/telemetry/components/usage-screen.tsx:198
msgid "Daily active players"
msgstr "デイリーアクティブプレイヤー数"
@@ -941,7 +953,7 @@ msgstr "修正により勝ち上がりの相手が変わったため、以降の
msgid "Duration"
msgstr "所要時間"
#: src/features/telemetry/components/usage-screen.tsx:241
#: src/features/telemetry/components/usage-screen.tsx:315
msgid "Duration p50 / p95"
msgstr "所要時間 p50 / p95"
@@ -1003,7 +1015,7 @@ msgstr "終了日(任意)"
msgid "End Match"
msgstr "試合を終了"
#: src/features/telemetry/components/usage-screen.tsx:160
#: src/features/telemetry/components/usage-screen.tsx:195
msgid "Engagement"
msgstr "エンゲージメント"
@@ -1107,10 +1119,18 @@ msgid "Error: {errorMessage}"
msgstr "エラー: {errorMessage}"
#: src/app/routes/_authed/admin/telemetry.tsx:57
#: src/features/telemetry/components/usage-screen.tsx:205
#: src/features/telemetry/components/usage-screen.tsx:260
msgid "Errors"
msgstr "エラー"
#: src/features/telemetry/components/usage-screen.tsx:289
msgid "Event"
msgstr "イベント"
#: src/features/telemetry/components/usage-screen.tsx:226
msgid "Events"
msgstr "イベント"
#: src/features/tournaments/components/group-stage-view.tsx:368
msgid "Expand standings"
msgstr "順位表を展開"
@@ -1236,7 +1256,7 @@ msgstr "フリーエージェント登録"
msgid "Free Agents"
msgstr "フリーエージェント"
#: src/features/telemetry/components/usage-screen.tsx:234
#: src/features/telemetry/components/usage-screen.tsx:308
msgid "Function"
msgstr "関数"
@@ -1618,7 +1638,7 @@ msgstr "対戦カード"
msgid "Matchup details"
msgstr "対戦カードの詳細"
#: src/features/telemetry/components/usage-screen.tsx:174
#: src/features/telemetry/components/usage-screen.tsx:209
msgid "MAU"
msgstr "MAU"
@@ -1731,10 +1751,18 @@ msgstr "アクティビティが見つかりません"
msgid "No Badges Available"
msgstr "利用可能なバッジがありません"
#: src/features/telemetry/components/usage-screen.tsx:146
msgid "No breakdown recorded"
msgstr "内訳の記録はありません"
#: src/features/spotify/components/spotify-sheet.tsx:154
msgid "No devices found."
msgstr "デバイスが見つかりません。"
#: src/features/telemetry/components/usage-screen.tsx:237
msgid "No events recorded in this range"
msgstr "この期間のイベントはありません"
#: src/features/tournaments/components/group-stage-view.tsx:294
msgid "No groups have been created yet"
msgstr "まだグループが作成されていません"
@@ -1922,15 +1950,15 @@ msgstr "概要"
msgid "owo"
msgstr "owo"
#: src/features/telemetry/components/usage-screen.tsx:101
#: src/features/telemetry/components/usage-screen.tsx:105
msgid "p50"
msgstr "p50"
#: src/features/telemetry/components/usage-screen.tsx:117
#: src/features/telemetry/components/usage-screen.tsx:121
msgid "p95"
msgstr "p95"
#: src/features/telemetry/components/usage-screen.tsx:181
#: src/features/telemetry/components/usage-screen.tsx:216
msgid "Page views by route"
msgstr "ルート別ページビュー数"
@@ -1964,6 +1992,14 @@ msgstr "電話番号の入力が必要です"
msgid "Phone number must be 10 digits"
msgstr "電話番号は10桁で入力してください"
#: src/features/telemetry/components/usage-screen.tsx:358
msgid "Pick a date range"
msgstr "期間を選択"
#: src/features/telemetry/components/usage-screen.tsx:380
msgid "Pick a date range to see usage"
msgstr "期間を選択すると利用状況が表示されます"
#: src/features/predictions/components/matchup-sheet.tsx:49
msgid "Pick the earlier matches first — these teams aren't decided yet."
msgstr "先に前の試合を選んでください — これらのチームはまだ決まっていません。"
@@ -2322,7 +2358,7 @@ msgstr "シリーズはタイです"
msgid "Server function failing"
msgstr "サーバー関数が失敗しています"
#: src/features/telemetry/components/usage-screen.tsx:191
#: src/features/telemetry/components/usage-screen.tsx:246
msgid "Server functions"
msgstr "サーバー関数"
@@ -2331,7 +2367,7 @@ msgid "serverFn name"
msgstr "serverFn名"
#: src/app/routes/_authed/admin/telemetry.tsx:54
#: src/features/telemetry/components/usage-screen.tsx:177
#: src/features/telemetry/components/usage-screen.tsx:212
msgid "Sessions"
msgstr "セッション数"
@@ -2667,10 +2703,14 @@ msgstr "各グループの上位{0, plural, one {#チーム} other {#チーム}}
msgid "Top {n} advance"
msgstr "上位{n}チームが勝ち上がり"
#: src/features/telemetry/components/usage-screen.tsx:195
#: src/features/telemetry/components/usage-screen.tsx:250
msgid "Top functions by call count"
msgstr "呼び出し数の多い関数"
#: src/features/telemetry/components/usage-screen.tsx:231
msgid "Top interactions, tap for breakdown"
msgstr "上位のインタラクション、タップで内訳を表示"
#: src/features/matches/components/team-head-to-head-sheet.tsx:158
#: src/features/players/components/player-head-to-head-sheet.tsx:193
msgid "Total Cups"
@@ -2826,7 +2866,7 @@ msgstr "予想を見る"
msgid "Viewport"
msgstr "ビューポート"
#: src/features/telemetry/components/usage-screen.tsx:219
#: src/features/telemetry/components/usage-screen.tsx:274
msgid "Vitals"
msgstr "バイタル"
@@ -2865,7 +2905,7 @@ msgstr "ウォークアウト区間({segmentDuration}秒)"
msgid "Walkout Song"
msgstr "ウォークアウトソング"
#: src/features/telemetry/components/usage-screen.tsx:170
#: src/features/telemetry/components/usage-screen.tsx:205
msgid "WAU"
msgstr "WAU"