milestone 21: abp list exceptions and a regex rule kind

This commit is contained in:
2026-08-13 19:14:47 +02:00
parent b340521716
commit 2ab7c1f1de
51 changed files with 4016 additions and 465 deletions
+14 -5
View File
@@ -15,6 +15,7 @@ import { READ_ONLY_HINT, useReadOnlyConfig } from "@/features/settings/authority
const KIND_OPTIONS = [
{ value: "exact", label: "exact" },
{ value: "wildcard", label: "wildcard" },
{ value: "regex", label: "regex" },
];
const ACTION_OPTIONS = [
@@ -97,10 +98,12 @@ export default function RulesPage() {
function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
create.mutate(
{ group_id: groupId, pattern: pattern.trim(), kind, action },
{ onSuccess: () => setPattern("") },
);
// A regex pattern is stored and matched byte for byte, so the UI must not
// edit it: trimming here would make a UI-created rule differ from the same
// bytes posted to /api/rules. Name-shaped kinds are normalized server-side,
// so trimming them only spares a pasted space a 400.
const sent = kind === "regex" ? pattern : pattern.trim();
create.mutate({ group_id: groupId, pattern: sent, kind, action }, { onSuccess: () => setPattern("") });
}
function confirmDelete() {
@@ -173,7 +176,13 @@ export default function RulesPage() {
required
value={pattern}
onChange={(event) => setPattern(event.target.value)}
placeholder="ads.example.com or *.example.com"
placeholder="ads.example.com, *.example.com or ^ad[0-9]+-"
// A phone keyboard capitalizing the first letter is silent for
// exact and wildcard (normalized server-side) but fatal for a
// regex, which matches the lowercase query name byte for byte.
autoCapitalize="none"
autoCorrect="off"
spellCheck={false}
{...stylex.props(shared.input, shared.focusRing)}
/>
</div>