mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-09 10:13:02 +02:00
Add statistics
This commit is contained in:
@@ -3,6 +3,10 @@ import { Separator } from '../ui/separator';
|
||||
import { api } from '../../api';
|
||||
import type { StatisticsResponse } from '../../types';
|
||||
|
||||
function formatPercent(value: number): string {
|
||||
return `${value.toFixed(1)}%`;
|
||||
}
|
||||
|
||||
export function SettingsStatisticsSection({ className }: { className?: string }) {
|
||||
const [stats, setStats] = useState<StatisticsResponse | null>(null);
|
||||
const [statsLoading, setStatsLoading] = useState(false);
|
||||
@@ -34,7 +38,9 @@ export function SettingsStatisticsSection({ className }: { className?: string })
|
||||
return (
|
||||
<div className={className}>
|
||||
{statsLoading && !stats ? (
|
||||
<div className="py-8 text-center text-muted-foreground">Loading statistics...</div>
|
||||
<div className="py-8 text-center text-muted-foreground">
|
||||
Loading statistics... this can take a while if you have a lot of stored packets.
|
||||
</div>
|
||||
) : stats ? (
|
||||
<div className="space-y-6">
|
||||
{/* Network */}
|
||||
@@ -100,6 +106,39 @@ export function SettingsStatisticsSection({ className }: { className?: string })
|
||||
|
||||
<Separator />
|
||||
|
||||
<div>
|
||||
<h4 className="text-sm font-medium mb-2">Path Hash Width (24h)</h4>
|
||||
<div className="mb-2 text-xs text-muted-foreground">
|
||||
Parsed stored raw packets from the last 24 hours:{' '}
|
||||
{stats.path_hash_width_24h.total_packets}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between items-center text-sm">
|
||||
<span>1-byte hops</span>
|
||||
<span className="text-muted-foreground">
|
||||
{stats.path_hash_width_24h.single_byte} (
|
||||
{formatPercent(stats.path_hash_width_24h.single_byte_pct)})
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center text-sm">
|
||||
<span>2-byte hops</span>
|
||||
<span className="text-muted-foreground">
|
||||
{stats.path_hash_width_24h.double_byte} (
|
||||
{formatPercent(stats.path_hash_width_24h.double_byte_pct)})
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center text-sm">
|
||||
<span>3-byte hops</span>
|
||||
<span className="text-muted-foreground">
|
||||
{stats.path_hash_width_24h.triple_byte} (
|
||||
{formatPercent(stats.path_hash_width_24h.triple_byte_pct)})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Activity */}
|
||||
<div>
|
||||
<h4 className="text-sm font-medium mb-2">Activity</h4>
|
||||
|
||||
@@ -378,6 +378,15 @@ describe('SettingsModal', () => {
|
||||
total_outgoing: 30,
|
||||
contacts_heard: { last_hour: 2, last_24_hours: 7, last_week: 10 },
|
||||
repeaters_heard: { last_hour: 1, last_24_hours: 3, last_week: 3 },
|
||||
path_hash_width_24h: {
|
||||
total_packets: 120,
|
||||
single_byte: 60,
|
||||
double_byte: 36,
|
||||
triple_byte: 24,
|
||||
single_byte_pct: 50,
|
||||
double_byte_pct: 30,
|
||||
triple_byte_pct: 20,
|
||||
},
|
||||
};
|
||||
|
||||
vi.spyOn(globalThis, 'fetch').mockResolvedValue(
|
||||
@@ -405,6 +414,14 @@ describe('SettingsModal', () => {
|
||||
expect(screen.getByText('Total stored')).toBeInTheDocument();
|
||||
expect(screen.getByText('Decrypted')).toBeInTheDocument();
|
||||
expect(screen.getByText('Undecrypted')).toBeInTheDocument();
|
||||
expect(screen.getByText('Path Hash Width (24h)')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/Parsed stored raw packets from the last 24 hours: 120/)
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText('1-byte hops')).toBeInTheDocument();
|
||||
expect(screen.getByText('60 (50.0%)')).toBeInTheDocument();
|
||||
expect(screen.getByText('36 (30.0%)')).toBeInTheDocument();
|
||||
expect(screen.getByText('24 (20.0%)')).toBeInTheDocument();
|
||||
expect(screen.getByText('Contacts heard')).toBeInTheDocument();
|
||||
expect(screen.getByText('Repeaters heard')).toBeInTheDocument();
|
||||
|
||||
@@ -427,6 +444,15 @@ describe('SettingsModal', () => {
|
||||
total_outgoing: 30,
|
||||
contacts_heard: { last_hour: 2, last_24_hours: 7, last_week: 10 },
|
||||
repeaters_heard: { last_hour: 1, last_24_hours: 3, last_week: 3 },
|
||||
path_hash_width_24h: {
|
||||
total_packets: 120,
|
||||
single_byte: 60,
|
||||
double_byte: 36,
|
||||
triple_byte: 24,
|
||||
single_byte_pct: 50,
|
||||
double_byte_pct: 30,
|
||||
triple_byte_pct: 20,
|
||||
},
|
||||
};
|
||||
|
||||
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
|
||||
|
||||
@@ -398,4 +398,13 @@ export interface StatisticsResponse {
|
||||
total_outgoing: number;
|
||||
contacts_heard: ContactActivityCounts;
|
||||
repeaters_heard: ContactActivityCounts;
|
||||
path_hash_width_24h: {
|
||||
total_packets: number;
|
||||
single_byte: number;
|
||||
double_byte: number;
|
||||
triple_byte: number;
|
||||
single_byte_pct: number;
|
||||
double_byte_pct: number;
|
||||
triple_byte_pct: number;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user