refactor(telemetry): text-only list empty states, distinct p50/p95 series
- paginated-list empty prop is a plain string, no icon block - second sparkline series drawn in dimmed color; area disabled on dual charts - duration legend shows latest p50/p95 values
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import { Trans, Plural, useLingui } from "@lingui/react/macro";
|
||||
import { Alert, Code, Container, Group, Stack, Text } from "@mantine/core";
|
||||
import { CheckIcon, XIcon, PulseIcon } from "@phosphor-icons/react";
|
||||
import { CheckIcon, XIcon } from "@phosphor-icons/react";
|
||||
import { Activity, ActivitySearchParams } from "../types";
|
||||
import { useActivities } from "../queries";
|
||||
import { usePlayers } from "@/features/players/queries";
|
||||
@@ -129,7 +129,7 @@ export const ActivitiesTable = () => {
|
||||
<PaginatedList
|
||||
items={items}
|
||||
keyOf={(activity) => activity.id}
|
||||
empty={{ icon: <PulseIcon size={32} />, title: t`No Activities Found` }}
|
||||
empty={t`No Activities Found`}
|
||||
page={page}
|
||||
totalPages={result.totalPages}
|
||||
onPageChange={setPage}
|
||||
|
||||
@@ -17,6 +17,7 @@ interface SparklineProps {
|
||||
showArea?: boolean;
|
||||
label?: string;
|
||||
color?: string;
|
||||
series2Color?: string;
|
||||
scale?: SparklineScale;
|
||||
}
|
||||
|
||||
@@ -27,6 +28,7 @@ export const Sparkline = ({
|
||||
showArea = false,
|
||||
label,
|
||||
color = "var(--mantine-color-anchor)",
|
||||
series2Color = "var(--mantine-color-dimmed)",
|
||||
scale,
|
||||
}: SparklineProps) => {
|
||||
if (data.length === 0) {
|
||||
@@ -42,7 +44,7 @@ export const Sparkline = ({
|
||||
const secondPath = series2?.length
|
||||
? pointsToPath(series2, VIEW_WIDTH, height, PAD, extent)
|
||||
: null;
|
||||
const areaPath = showArea
|
||||
const areaPath = showArea && !secondPath
|
||||
? `${path} L${VIEW_WIDTH - PAD},${height - PAD} L${PAD},${height - PAD} Z`
|
||||
: null;
|
||||
|
||||
@@ -74,7 +76,7 @@ export const Sparkline = ({
|
||||
<path
|
||||
d={secondPath}
|
||||
fill="none"
|
||||
stroke={color}
|
||||
stroke={series2Color}
|
||||
strokeWidth={2}
|
||||
strokeDasharray="4 3"
|
||||
strokeLinecap="round"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import { Trans, Plural, useLingui } from "@lingui/react/macro";
|
||||
import { Code, Container, Stack } from "@mantine/core";
|
||||
import { CursorClickIcon } from "@phosphor-icons/react";
|
||||
import { usePlayers } from "@/features/players/queries";
|
||||
import { useSheet } from "@/hooks/use-sheet";
|
||||
import { useClientEvents } from "../queries";
|
||||
@@ -91,7 +90,7 @@ export const ClientEventsTable = () => {
|
||||
<PaginatedList
|
||||
items={result.items}
|
||||
keyOf={(event) => event.id}
|
||||
empty={{ icon: <CursorClickIcon size={32} />, title: t`No Events Found` }}
|
||||
empty={t`No Events Found`}
|
||||
page={page}
|
||||
totalPages={result.totalPages}
|
||||
onPageChange={setPage}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { ReactNode } from "react";
|
||||
import { Box, Divider, Group, Pagination, Stack } from "@mantine/core";
|
||||
import EmptyState from "@/components/empty-state";
|
||||
import { Box, Divider, Group, Pagination, Stack, Text } from "@mantine/core";
|
||||
|
||||
interface PaginatedListProps<T> {
|
||||
items: T[];
|
||||
renderItem: (item: T) => ReactNode;
|
||||
keyOf: (item: T) => string;
|
||||
empty: { icon: ReactNode; title: string; description?: string };
|
||||
empty: string;
|
||||
page?: number;
|
||||
totalPages?: number;
|
||||
onPageChange?: (page: number) => void;
|
||||
@@ -32,7 +31,9 @@ export const PaginatedList = <T,>({
|
||||
</Stack>
|
||||
|
||||
{items.length === 0 && (
|
||||
<EmptyState icon={empty.icon} title={empty.title} description={empty.description} />
|
||||
<Text size="sm" c="dimmed" px="md" py="xl" ta="center">
|
||||
{empty}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{totalPages > 1 && onPageChange && (
|
||||
|
||||
@@ -77,6 +77,8 @@ const FnDurationDetail = ({ fn, from, to }: { fn: string; from: string; to: stri
|
||||
const days = listDays({ from, to });
|
||||
const p50 = fillDailySeries(rows, "server_fn.duration.p50", fn, days);
|
||||
const p95 = fillDailySeries(rows, "server_fn.duration.p95", fn, days);
|
||||
const lastNonZero = (series: number[]) =>
|
||||
[...series].reverse().find((value) => value > 0) ?? 0;
|
||||
|
||||
return (
|
||||
<Stack gap="xs">
|
||||
@@ -84,7 +86,6 @@ const FnDurationDetail = ({ fn, from, to }: { fn: string; from: string; to: stri
|
||||
data={p50}
|
||||
series2={p95}
|
||||
height={64}
|
||||
showArea
|
||||
scale={{
|
||||
start: dayLabel(i18n, from),
|
||||
end: dayLabel(i18n, to),
|
||||
@@ -97,7 +98,7 @@ const FnDurationDetail = ({ fn, from, to }: { fn: string; from: string; to: stri
|
||||
<line x1={0} y1={4} x2={18} y2={4} stroke="var(--mantine-color-anchor)" strokeWidth={2} />
|
||||
</svg>
|
||||
<Text size="xs" c="dimmed">
|
||||
<Trans>p50</Trans>
|
||||
<Trans>p50</Trans> · {Math.round(lastNonZero(p50))}ms
|
||||
</Text>
|
||||
</Group>
|
||||
<Group gap={6}>
|
||||
@@ -107,13 +108,13 @@ const FnDurationDetail = ({ fn, from, to }: { fn: string; from: string; to: stri
|
||||
y1={4}
|
||||
x2={18}
|
||||
y2={4}
|
||||
stroke="var(--mantine-color-anchor)"
|
||||
stroke="var(--mantine-color-dimmed)"
|
||||
strokeWidth={2}
|
||||
strokeDasharray="4 3"
|
||||
/>
|
||||
</svg>
|
||||
<Text size="xs" c="dimmed">
|
||||
<Trans>p95</Trans>
|
||||
<Trans>p95</Trans> · {Math.round(lastNonZero(p95))}ms
|
||||
</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
|
||||
Reference in New Issue
Block a user