Skip to content

Commit 2526746

Browse files
authored
refactor(dashboard): allow speedtest history server filtering (#109)
1 parent 6679aef commit 2526746

3 files changed

Lines changed: 501 additions & 16 deletions

File tree

web/src/components/Main.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ export default function Main({ isPublic = false }: MainProps) {
538538
}}
539539
/>
540540
</motion.div>
541-
)}
541+
)}
542542

543543
{!isPublic && activeTab === "speedtest" && (
544544
<motion.div

web/src/components/speedtest/DashboardTab.tsx

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
"use client";
77

8-
import React, { useState, useEffect } from "react";
8+
import React, { useState, useEffect, useMemo } from "react";
99
import { motion } from "motion/react";
1010
import { SpeedTestResult, TimeRange } from "@/types/types";
1111
import { SpeedHistoryChart } from "./SpeedHistoryChart";
@@ -119,6 +119,16 @@ interface DraggableSpeedHistoryChartProps {
119119
dragHandleRef?: (node: HTMLElement | null) => void;
120120
dragHandleListeners?: Record<string, (...args: unknown[]) => unknown>;
121121
dragHandleClassName?: string;
122+
// Server filtering props
123+
serverFilterMode: "all" | "single" | "multiple";
124+
selectedSingleServer: string;
125+
selectedMultipleServers: Set<string>;
126+
onServerFilterModeChange: (mode: "all" | "single" | "multiple") => void;
127+
onSelectedSingleServerChange: (server: string) => void;
128+
onSelectedMultipleServersChange: (servers: Set<string>) => void;
129+
// Multiple server display mode props
130+
multipleServerDisplayMode: "overlay" | "separate";
131+
onMultipleServerDisplayModeChange: (mode: "overlay" | "separate") => void;
122132
}
123133

124134
const DraggableSpeedHistoryChart: React.FC<DraggableSpeedHistoryChartProps> = ({
@@ -171,6 +181,12 @@ export const DashboardTab: React.FC<DashboardTabProps> = ({
171181
// State for share button hover
172182
const [isShareHovered, setIsShareHovered] = useState(false);
173183

184+
// Server filtering state
185+
const [serverFilterMode, setServerFilterMode] = useState<"all" | "single" | "multiple">("all");
186+
const [selectedSingleServer, setSelectedSingleServer] = useState<string>("all");
187+
const [selectedMultipleServers, setSelectedMultipleServers] = useState<Set<string>>(new Set());
188+
const [multipleServerDisplayMode, setMultipleServerDisplayMode] = useState<"overlay" | "separate">("overlay");
189+
174190
// Initialize drag sensors
175191
const sensors = useSensors(
176192
useSensor(PointerSensor),
@@ -194,10 +210,26 @@ export const DashboardTab: React.FC<DashboardTabProps> = ({
194210

195211
const displayedTests = tests.slice(0, displayCount);
196212

213+
// Apply server filtering to tests (same logic as in SpeedHistoryChart)
214+
const filteredDisplayTests = useMemo(() => {
215+
if (serverFilterMode === "single" && selectedSingleServer !== "all") {
216+
return tests.filter(test => test.serverName === selectedSingleServer);
217+
} else if (serverFilterMode === "multiple" && selectedMultipleServers.size > 0) {
218+
return tests.filter(test => selectedMultipleServers.has(test.serverName));
219+
}
220+
return tests;
221+
}, [tests, serverFilterMode, selectedSingleServer, selectedMultipleServers]);
222+
223+
// Get the latest test from filtered results
224+
const filteredLatestTestComputed = useMemo(() => {
225+
return filteredDisplayTests.length > 0 ? filteredDisplayTests[filteredDisplayTests.length - 1] : null;
226+
}, [filteredDisplayTests]);
227+
197228
const calculateAverage = (field: keyof SpeedTestResult): string => {
198-
if (tests.length === 0) return "N/A";
229+
const dataToUse = filteredDisplayTests.length > 0 ? filteredDisplayTests : tests;
230+
if (dataToUse.length === 0) return "N/A";
199231

200-
const validValues = tests
232+
const validValues = dataToUse
201233
.map((test) => {
202234
const value = test[field];
203235
if (typeof value === "string") {
@@ -306,31 +338,31 @@ export const DashboardTab: React.FC<DashboardTabProps> = ({
306338
<MetricCard
307339
icon={<IoIosPulse className="w-5 h-5 text-amber-500" />}
308340
title="Latency"
309-
value={parseFloat(latestTest.latency).toFixed(2)}
341+
value={parseFloat((filteredLatestTestComputed || latestTest)!.latency).toFixed(2)}
310342
unit="ms"
311343
average={calculateAverage("latency")}
312344
/>
313345
<MetricCard
314346
icon={<FaArrowDown className="w-5 h-5 text-blue-500" />}
315347
title="Download"
316-
value={latestTest.downloadSpeed.toFixed(2)}
348+
value={(filteredLatestTestComputed || latestTest)!.downloadSpeed.toFixed(2)}
317349
unit="Mbps"
318350
average={calculateAverage("downloadSpeed")}
319351
/>
320352
<MetricCard
321353
icon={<FaArrowUp className="w-5 h-5 text-emerald-500" />}
322354
title="Upload"
323-
value={latestTest.uploadSpeed.toFixed(2)}
355+
value={(filteredLatestTestComputed || latestTest)!.uploadSpeed.toFixed(2)}
324356
unit="Mbps"
325357
average={calculateAverage("uploadSpeed")}
326358
/>
327359
<MetricCard
328360
icon={<FaWaveSquare className="w-5 h-5 text-purple-400" />}
329361
title="Jitter"
330-
value={latestTest.jitter?.toFixed(2) ?? "N/A"}
362+
value={(filteredLatestTestComputed || latestTest)!.jitter?.toFixed(2) ?? "N/A"}
331363
unit="ms"
332364
average={
333-
latestTest.jitter ? calculateAverage("jitter") : undefined
365+
(filteredLatestTestComputed || latestTest)!.jitter ? calculateAverage("jitter") : undefined
334366
}
335367
/>
336368

@@ -387,6 +419,14 @@ export const DashboardTab: React.FC<DashboardTabProps> = ({
387419
isPublic={isPublic}
388420
hasAnyTests={hasAnyTests}
389421
hasCurrentRangeTests={tests.length > 0}
422+
serverFilterMode={serverFilterMode}
423+
selectedSingleServer={selectedSingleServer}
424+
selectedMultipleServers={selectedMultipleServers}
425+
onServerFilterModeChange={setServerFilterMode}
426+
onSelectedSingleServerChange={setSelectedSingleServer}
427+
onSelectedMultipleServersChange={setSelectedMultipleServers}
428+
multipleServerDisplayMode={multipleServerDisplayMode}
429+
onMultipleServerDisplayModeChange={setMultipleServerDisplayMode}
390430
/>
391431
</SortableItem>
392432
);

0 commit comments

Comments
 (0)