mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-24 13:56:39 +00:00
✨Add request by day chart
This commit is contained in:
@@ -121,6 +121,7 @@ async function query(query: Q) {
|
|||||||
totalCount: sql<number>`COUNT(*)`.as("total_count")
|
totalCount: sql<number>`COUNT(*)`.as("total_count")
|
||||||
})
|
})
|
||||||
.from(requestAuditLog)
|
.from(requestAuditLog)
|
||||||
|
.where(and(baseConditions))
|
||||||
.groupBy(groupByDayFunction)
|
.groupBy(groupByDayFunction)
|
||||||
.orderBy(groupByDayFunction);
|
.orderBy(groupByDayFunction);
|
||||||
|
|
||||||
|
|||||||
@@ -347,6 +347,9 @@ function RequestChart(props: RequestChartProps) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const chartConfig = {
|
const chartConfig = {
|
||||||
|
day: {
|
||||||
|
label: t("requestsByDay")
|
||||||
|
},
|
||||||
blockedCount: {
|
blockedCount: {
|
||||||
label: t("blocked"),
|
label: t("blocked"),
|
||||||
color: "var(--chart-5)"
|
color: "var(--chart-5)"
|
||||||
@@ -367,49 +370,14 @@ function RequestChart(props: RequestChartProps) {
|
|||||||
<ChartTooltip
|
<ChartTooltip
|
||||||
content={
|
content={
|
||||||
<ChartTooltipContent
|
<ChartTooltipContent
|
||||||
hideLabel
|
indicator="dot"
|
||||||
formatter={(value, name, item, index) => {
|
labelFormatter={(value, payload) => {
|
||||||
const formattedDate = new Date(
|
const formattedDate = new Date(
|
||||||
item.payload.day
|
payload[0].payload.day
|
||||||
).toLocaleDateString(navigator.language, {
|
).toLocaleDateString(navigator.language, {
|
||||||
dateStyle: "medium"
|
dateStyle: "medium"
|
||||||
});
|
});
|
||||||
|
return formattedDate;
|
||||||
const value_str = numberFormatter.format(
|
|
||||||
value as number
|
|
||||||
);
|
|
||||||
|
|
||||||
const config =
|
|
||||||
chartConfig[
|
|
||||||
name as keyof typeof chartConfig
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex gap-2 items-start text-sm flex-col w-full">
|
|
||||||
{index === 0 && (
|
|
||||||
<span>{formattedDate}</span>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="ml-auto flex items-baseline justify-between gap-4 self-stretch w-full font-mono font-medium tabular-nums text-card-foreground text-xs">
|
|
||||||
<div className="flex gap-1 items-center">
|
|
||||||
<div
|
|
||||||
className="size-2.5 flex-none rounded-[2px] bg-(--color-bg)"
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
"--color-bg": `var(--color-${name})`
|
|
||||||
} as React.CSSProperties
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<span className="text-muted-foreground">
|
|
||||||
{config.label}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-0.5">
|
|
||||||
<span>{value_str}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@@ -486,13 +454,15 @@ function RequestChart(props: RequestChartProps) {
|
|||||||
<Area
|
<Area
|
||||||
dataKey="allowedCount"
|
dataKey="allowedCount"
|
||||||
stroke="var(--color-allowedCount)"
|
stroke="var(--color-allowedCount)"
|
||||||
fill="url(#fillAllowed)"
|
strokeWidth={2}
|
||||||
|
fill="transparent"
|
||||||
radius={4}
|
radius={4}
|
||||||
/>
|
/>
|
||||||
<Area
|
<Area
|
||||||
dataKey="blockedCount"
|
dataKey="blockedCount"
|
||||||
stroke="var(--color-blockedCount)"
|
stroke="var(--color-blockedCount)"
|
||||||
fill="url(#fillBlocked)"
|
strokeWidth={2}
|
||||||
|
fill="transparent"
|
||||||
radius={4}
|
radius={4}
|
||||||
/>
|
/>
|
||||||
</AreaChart>
|
</AreaChart>
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ const ChartTooltipContent = React.forwardRef<
|
|||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
|
"grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -190,6 +190,7 @@ const ChartTooltipContent = React.forwardRef<
|
|||||||
.filter((item) => item.type !== "none")
|
.filter((item) => item.type !== "none")
|
||||||
.map((item, index) => {
|
.map((item, index) => {
|
||||||
const key = `${nameKey || item.name || item.dataKey || "value"}`;
|
const key = `${nameKey || item.name || item.dataKey || "value"}`;
|
||||||
|
|
||||||
const itemConfig = getPayloadConfigFromPayload(
|
const itemConfig = getPayloadConfigFromPayload(
|
||||||
config,
|
config,
|
||||||
item,
|
item,
|
||||||
@@ -224,7 +225,7 @@ const ChartTooltipContent = React.forwardRef<
|
|||||||
!hideIndicator && (
|
!hideIndicator && (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",
|
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
|
||||||
{
|
{
|
||||||
"h-2.5 w-2.5":
|
"h-2.5 w-2.5":
|
||||||
indicator ===
|
indicator ===
|
||||||
@@ -254,7 +255,7 @@ const ChartTooltipContent = React.forwardRef<
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex flex-1 justify-between leading-none",
|
"flex flex-1 justify-between leading-none gap-2",
|
||||||
nestLabel
|
nestLabel
|
||||||
? "items-end"
|
? "items-end"
|
||||||
: "items-center"
|
: "items-center"
|
||||||
@@ -271,7 +272,18 @@ const ChartTooltipContent = React.forwardRef<
|
|||||||
</div>
|
</div>
|
||||||
{item.value && (
|
{item.value && (
|
||||||
<span className="font-mono font-medium tabular-nums text-foreground">
|
<span className="font-mono font-medium tabular-nums text-foreground">
|
||||||
{item.value.toLocaleString()}
|
{!isNaN(
|
||||||
|
item.value as number
|
||||||
|
)
|
||||||
|
? new Intl.NumberFormat(
|
||||||
|
navigator.language,
|
||||||
|
{
|
||||||
|
maximumFractionDigits: 0
|
||||||
|
}
|
||||||
|
).format(
|
||||||
|
item.value as number
|
||||||
|
)
|
||||||
|
: item.value.toLocaleString()}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user