Merge pull request #344 from ipnet-mesh/fix/routes-stats-label-tweaks

Compact Routes stats dash and chart 'Now' label
This commit is contained in:
JingleManSweep
2026-07-24 23:51:51 +01:00
committed by GitHub
4 changed files with 52 additions and 6 deletions
@@ -74,6 +74,52 @@ describe("Routes", () => {
).not.toBeNull();
});
it("renders matched/threshold/degraded stat with dash separator", async () => {
const data = {
items: [
{
...ROUTES.items[0],
route_result: {
quality: "clear",
state: "healthy",
matched_count: 3,
threshold: 5,
effective_clear: 2,
},
},
],
};
vi.spyOn(api, "apiGet").mockImplementation(async (path) => {
if (path === "/api/v1/routes") return data;
if (path.match(/\/api\/v1\/routes\/[^/]+$/)) return ROUTE_DETAIL;
if (path.includes("/history")) return ROUTE_HISTORY;
throw new Error(`Unexpected: ${path}`);
});
renderWithProviders(<Routes />);
await waitFor(() => {
expect(screen.getByText("3/5-2")).toBeInTheDocument();
});
});
it("shows Now label for the last history chart entry", async () => {
const historyWithData = {
data: [
{ date: "2026-07-20", matched: 0, total: 0 },
{ date: "2026-07-21", matched: 1, total: 1 },
],
};
vi.spyOn(api, "apiGet").mockImplementation(async (path) => {
if (path === "/api/v1/routes") return ROUTES;
if (path.match(/\/api\/v1\/routes\/[^/]+$/)) return ROUTE_DETAIL;
if (path.includes("/history")) return historyWithData;
throw new Error(`Unexpected: ${path}`);
});
renderWithProviders(<Routes />);
await waitFor(() => {
expect(screen.getByText("common.now")).toBeInTheDocument();
});
});
it("shows an error on fetch failure", async () => {
vi.spyOn(api, "apiGet").mockRejectedValue(new Error("routes error"));
renderWithProviders(<Routes />);
@@ -310,7 +310,7 @@ function StatsRow({ route }: { route: RouteItem }) {
<IconPackets className="h-3.5 w-3.5" />
<span>
{matched}/{threshold}
{"\u2192"}
{"-"}
{degraded}
</span>
</span>
@@ -473,7 +473,7 @@ function DetailContent({
{historyData.map((d, i) => (
<span key={d.date} className="flex-1 text-center min-w-0 truncate">
{i === historyData.length - 1
? t("routes.last_n_hours", { n: route.window_hours })
? t("common.now")
: new Date(`${d.date}T00:00:00`).toLocaleDateString(
undefined,
{ day: "2-digit", month: "2-digit" },
+2 -2
View File
@@ -117,7 +117,8 @@
"unnamed_node": "Unnamed Node",
"validation_invalid_number": "Value must be a valid number",
"validation_invalid_boolean": "Value must be true, false, yes, no, 1, or 0",
"sort_by": "Sort by"
"sort_by": "Sort by",
"now": "Now"
},
"links": {
"website": "Website",
@@ -359,7 +360,6 @@
"quality_no_coverage": "No Coverage",
"quality_unknown": "Unknown",
"recent_packets": "Recent Packets",
"last_n_hours": "Last {{n}}h",
"min_nodes_error": "At least 2 path nodes are required.",
"other_routes": "Other routes",
"filter_mine": "Show only my routes"
+2 -2
View File
@@ -108,7 +108,8 @@
"filter_operator_label": "Operator",
"filter_observer_label": "Waarnemer",
"filter_observer_enable": "Klik om deze waarnemer te tonen",
"filter_observer_disable": "Klik om deze waarnemer te verbergen"
"filter_observer_disable": "Klik om deze waarnemer te verbergen",
"now": "Nu"
},
"links": {
"website": "Website",
@@ -282,7 +283,6 @@
"quality_no_coverage": "Geen dekking",
"quality_unknown": "Onbekend",
"recent_packets": "Recente packets",
"last_n_hours": "Laatste {{n}}u",
"min_nodes_error": "Minimaal 2 padknooppunten zijn vereist.",
"other_routes": "Overige routes",
"filter_mine": "Toon alleen mijn routes"