activity: select-only multi-client filter

the freetype client field is gone. the picker is a select-only menu of known clients with multi-select, chips for the active set, and a 32-client cap shared with the server. the api accepts a comma-separated client list and filters any-of with bound parameters. the trigger carets come from phosphor icons, newly adopted. bundle budget rises to 900000 bytes for the picker and the icon dependency.
This commit is contained in:
2026-08-31 17:40:07 +02:00
parent d79dd0bbcb
commit b774b05456
12 changed files with 1093 additions and 130 deletions
+29 -1
View File
@@ -1,4 +1,12 @@
import { validateActivitySearch, validateBlocked, validateMode, validateText, validateTimestamp } from "./search";
import {
validateActivitySearch,
validateBlocked,
validateMode,
validateText,
validateTimestamp,
MAX_CLIENTS,
validateClients,
} from "./search";
test("mode is the two-value union, defaulting to history", () => {
expect(validateMode("live")).toBe("live");
@@ -111,3 +119,23 @@ test("a search of junk applies nothing", () => {
blocked: undefined,
});
});
test("the client list is canonicalized once, so the chips and the request agree", () => {
expect(validateClients("192.0.2.10,192.0.2.11")).toBe("192.0.2.10,192.0.2.11");
// Blanks name no client and a repeat asks for the same client twice, so
// neither changes which rows come back: dropping them is the same filter
// written once, not a different one.
expect(validateClients(" 192.0.2.10 , ,192.0.2.11,192.0.2.10,")).toBe("192.0.2.10,192.0.2.11");
expect(validateClients(",,")).toBeUndefined();
expect(validateClients("")).toBeUndefined();
expect(validateClients(null)).toBeUndefined();
});
test("a pasted list past the cap is cut to what the api will accept", () => {
const addresses = Array.from({ length: MAX_CLIENTS + 8 }, (_, index) => `198.51.100.${index + 1}`);
// The API refuses a longer list outright, so keeping the extra addresses
// would show a filter that cannot be applied at all.
expect(validateClients(addresses.join(","))).toBe(addresses.slice(0, MAX_CLIENTS).join(","));
});