mirror of
https://github.com/fosrl/pangolin.git
synced 2026-01-28 22:00:51 +00:00
🚸 show a better loading state for analytics
This commit is contained in:
@@ -1281,6 +1281,7 @@
|
||||
"setupErrorCreateAdmin": "An error occurred while creating the server admin account.",
|
||||
"certificateStatus": "Certificate Status",
|
||||
"loading": "Loading",
|
||||
"loadingAnalytics": "Loading Analytics",
|
||||
"restart": "Restart",
|
||||
"domains": "Domains",
|
||||
"domainsDescription": "Create and manage domains available in the organization",
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
TooltipTrigger
|
||||
} from "./ui/tooltip";
|
||||
import { getSevenDaysAgo } from "@app/lib/getSevenDaysAgo";
|
||||
import type { QueryRequestAnalyticsResponse } from "@server/routers/auditLogs";
|
||||
|
||||
export type AnalyticsContentProps = {
|
||||
orgId: string;
|
||||
@@ -276,13 +277,32 @@ export function LogAnalyticsData(props: AnalyticsContentProps) {
|
||||
</CardHeader>
|
||||
</Card>
|
||||
|
||||
<Card className="w-full h-full flex flex-col gap-8">
|
||||
<Card className="w-full h-full flex flex-col gap-8 relative">
|
||||
{isLoadingAnalytics && (
|
||||
<div className="absolute z-20 left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 border border-border rounded-md bg-muted">
|
||||
<div className="flex items-center gap-2 p-6">
|
||||
<LoaderIcon className="size-4 animate-spin" />
|
||||
{t("loadingAnalytics")}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<CardHeader>
|
||||
<h3 className="font-semibold">{t("requestsByDay")}</h3>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<CardContent className="relative">
|
||||
{isLoadingAnalytics && (
|
||||
<div className="backdrop-blur-[2px] z-10 absolute inset-0"></div>
|
||||
)}
|
||||
<RequestChart
|
||||
data={stats?.requestsPerDay ?? []}
|
||||
className={cn(
|
||||
isLoadingAnalytics &&
|
||||
"opacity-50 pointer-events-none"
|
||||
)}
|
||||
data={
|
||||
stats?.requestsPerDay ??
|
||||
generateSampleDailyRequests()
|
||||
}
|
||||
isLoading={isLoadingAnalytics}
|
||||
/>
|
||||
</CardContent>
|
||||
@@ -323,6 +343,28 @@ export function LogAnalyticsData(props: AnalyticsContentProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function generateSampleDailyRequests(): QueryRequestAnalyticsResponse["requestsPerDay"] {
|
||||
const today = new Date();
|
||||
|
||||
// generate sample data for the last 7 days
|
||||
const requestsPerDay = Array.from({ length: 7 }, (_, i) => {
|
||||
const date = new Date(today);
|
||||
date.setDate(date.getDate() - (6 - i));
|
||||
// generate a random number of requests between 1 and 100
|
||||
const totalCount = Math.floor(Math.random() * 100) + 1;
|
||||
// generate a random number of requests between 1 and totalCount
|
||||
const blockedCount = Math.floor(Math.random() * (totalCount + 1));
|
||||
return {
|
||||
day: date.toISOString().split("T")[0],
|
||||
allowedCount: totalCount - blockedCount,
|
||||
blockedCount,
|
||||
totalCount
|
||||
};
|
||||
});
|
||||
|
||||
return requestsPerDay;
|
||||
}
|
||||
|
||||
type RequestChartProps = {
|
||||
data: {
|
||||
day: string;
|
||||
@@ -331,6 +373,7 @@ type RequestChartProps = {
|
||||
totalCount: number;
|
||||
}[];
|
||||
isLoading: boolean;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
function RequestChart(props: RequestChartProps) {
|
||||
@@ -359,7 +402,7 @@ function RequestChart(props: RequestChartProps) {
|
||||
return (
|
||||
<ChartContainer
|
||||
config={chartConfig}
|
||||
className="min-h-[200px] w-full h-80"
|
||||
className={cn("min-h-50 w-full h-80", props.className)}
|
||||
>
|
||||
<LineChart accessibilityLayer data={props.data}>
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
|
||||
Reference in New Issue
Block a user