Skip to content

Commit c5437d8

Browse files
Merge pull request #344 from ipnet-mesh/fix/routes-stats-label-tweaks
Compact Routes stats dash and chart 'Now' label
2 parents fea1278 + 41f8e39 commit c5437d8

4 files changed

Lines changed: 52 additions & 6 deletions

File tree

src/meshcore_hub/web/static/js/spa-react/pages/Routes.test.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,52 @@ describe("Routes", () => {
7474
).not.toBeNull();
7575
});
7676

77+
it("renders matched/threshold/degraded stat with dash separator", async () => {
78+
const data = {
79+
items: [
80+
{
81+
...ROUTES.items[0],
82+
route_result: {
83+
quality: "clear",
84+
state: "healthy",
85+
matched_count: 3,
86+
threshold: 5,
87+
effective_clear: 2,
88+
},
89+
},
90+
],
91+
};
92+
vi.spyOn(api, "apiGet").mockImplementation(async (path) => {
93+
if (path === "/api/v1/routes") return data;
94+
if (path.match(/\/api\/v1\/routes\/[^/]+$/)) return ROUTE_DETAIL;
95+
if (path.includes("/history")) return ROUTE_HISTORY;
96+
throw new Error(`Unexpected: ${path}`);
97+
});
98+
renderWithProviders(<Routes />);
99+
await waitFor(() => {
100+
expect(screen.getByText("3/5-2")).toBeInTheDocument();
101+
});
102+
});
103+
104+
it("shows Now label for the last history chart entry", async () => {
105+
const historyWithData = {
106+
data: [
107+
{ date: "2026-07-20", matched: 0, total: 0 },
108+
{ date: "2026-07-21", matched: 1, total: 1 },
109+
],
110+
};
111+
vi.spyOn(api, "apiGet").mockImplementation(async (path) => {
112+
if (path === "/api/v1/routes") return ROUTES;
113+
if (path.match(/\/api\/v1\/routes\/[^/]+$/)) return ROUTE_DETAIL;
114+
if (path.includes("/history")) return historyWithData;
115+
throw new Error(`Unexpected: ${path}`);
116+
});
117+
renderWithProviders(<Routes />);
118+
await waitFor(() => {
119+
expect(screen.getByText("common.now")).toBeInTheDocument();
120+
});
121+
});
122+
77123
it("shows an error on fetch failure", async () => {
78124
vi.spyOn(api, "apiGet").mockRejectedValue(new Error("routes error"));
79125
renderWithProviders(<Routes />);

src/meshcore_hub/web/static/js/spa-react/pages/Routes.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ function StatsRow({ route }: { route: RouteItem }) {
310310
<IconPackets className="h-3.5 w-3.5" />
311311
<span>
312312
{matched}/{threshold}
313-
{"\u2192"}
313+
{"-"}
314314
{degraded}
315315
</span>
316316
</span>
@@ -473,7 +473,7 @@ function DetailContent({
473473
{historyData.map((d, i) => (
474474
<span key={d.date} className="flex-1 text-center min-w-0 truncate">
475475
{i === historyData.length - 1
476-
? t("routes.last_n_hours", { n: route.window_hours })
476+
? t("common.now")
477477
: new Date(`${d.date}T00:00:00`).toLocaleDateString(
478478
undefined,
479479
{ day: "2-digit", month: "2-digit" },

src/meshcore_hub/web/static/locales/en.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@
117117
"unnamed_node": "Unnamed Node",
118118
"validation_invalid_number": "Value must be a valid number",
119119
"validation_invalid_boolean": "Value must be true, false, yes, no, 1, or 0",
120-
"sort_by": "Sort by"
120+
"sort_by": "Sort by",
121+
"now": "Now"
121122
},
122123
"links": {
123124
"website": "Website",
@@ -359,7 +360,6 @@
359360
"quality_no_coverage": "No Coverage",
360361
"quality_unknown": "Unknown",
361362
"recent_packets": "Recent Packets",
362-
"last_n_hours": "Last {{n}}h",
363363
"min_nodes_error": "At least 2 path nodes are required.",
364364
"other_routes": "Other routes",
365365
"filter_mine": "Show only my routes"

src/meshcore_hub/web/static/locales/nl.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@
108108
"filter_operator_label": "Operator",
109109
"filter_observer_label": "Waarnemer",
110110
"filter_observer_enable": "Klik om deze waarnemer te tonen",
111-
"filter_observer_disable": "Klik om deze waarnemer te verbergen"
111+
"filter_observer_disable": "Klik om deze waarnemer te verbergen",
112+
"now": "Nu"
112113
},
113114
"links": {
114115
"website": "Website",
@@ -282,7 +283,6 @@
282283
"quality_no_coverage": "Geen dekking",
283284
"quality_unknown": "Onbekend",
284285
"recent_packets": "Recente packets",
285-
"last_n_hours": "Laatste {{n}}u",
286286
"min_nodes_error": "Minimaal 2 padknooppunten zijn vereist.",
287287
"other_routes": "Overige routes",
288288
"filter_mine": "Toon alleen mijn routes"

0 commit comments

Comments
 (0)