Make disabled records obvious, and offer the right fix when checking a blocked name
Disabled records are hatched and badged next to their name. Checking a name blocked by your own rule for that name offers to remove the rule, instead of an allow rule that would be refused as a duplicate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ad8eb3fc3d
commit
67f14b030f
4 files changed
+55
-15
No files matched your search
@@ -35,7 +35,7 @@ export async function render(el, params, query) {
|
||||
if (!name) return;
|
||||
try {
|
||||
const res = await get("/blocking/check", { name });
|
||||
mount(checkOut, checkResult(name, res, writable));
|
||||
mount(checkOut, checkResult(name, res, rules, writable));
|
||||
} catch (e) { mount(checkOut, errorBox(e)); }
|
||||
};
|
||||
|
||||
@@ -80,21 +80,48 @@ async function pause(minutes) {
|
||||
} catch (e) { toast(e.message, "err", 8000); }
|
||||
}
|
||||
|
||||
function checkResult(name, res, writable) {
|
||||
// checkResult shows what blocking does with a name, and offers the way
|
||||
// to stop it: an allow rule (it beats every list, and a rule for a parent
|
||||
// domain), or, when your own block rule is for this very name, removing
|
||||
// that rule (a second rule for the same name isn't allowed).
|
||||
function checkResult(name, res, rules, writable) {
|
||||
if (!res.length) return h("p", { class: "muted" }, "Blocking isn't used in any view yet: add a rule or a blocklist below.");
|
||||
const blocked = res.some((m) => m.result === "blocked");
|
||||
const n = name.trim().toLowerCase().replace(/\.$/, "");
|
||||
const ruleById = new Map(rules.map((r) => [r.id, r]));
|
||||
const blocked = res.filter((m) => m.result === "blocked");
|
||||
const ownBlocks = [...new Set(blocked.map((m) => ruleById.get(m.rule_id)).filter((r) => r && r.name === n))];
|
||||
const sameName = rules.filter((r) => r.name === n && !ownBlocks.includes(r));
|
||||
let action = null;
|
||||
if (writable && ownBlocks.length) {
|
||||
action = h("p", null, h("button", { class: "small", onclick: () => removeRules(ownBlocks) }, "Remove your block rule for " + n),
|
||||
h("span", { class: "muted small" }, ownBlocks.some((r) => !r.exact) ? " (it also covers the names below it)" : ""));
|
||||
} else if (writable && blocked.length && !sameName.length) {
|
||||
action = h("p", null, h("button", { class: "small", onclick: () => addRule(n, "allow", false, []) }, "Allow " + n),
|
||||
h("span", { class: "muted small" }, " adds an allow rule for it and the names below it, which beats every list and any rule for a parent domain."));
|
||||
} else if (writable && blocked.length) {
|
||||
action = h("p", { class: "muted small" }, "There already is a rule for " + n + " (in other views): change it under Your rules.");
|
||||
}
|
||||
return h("div", null,
|
||||
h("ul", { class: "plain" }, res.map((m) => h("li", null,
|
||||
m.view ? h("span", { class: "muted" }, "view " + m.view + ": ") : null,
|
||||
m.result === "blocked" ? badge("blocked", "err") : m.result === "allowed" ? badge("allowed", "ok") : badge("not blocked", ""),
|
||||
" ",
|
||||
m.list ? ["by blocklist ", h("strong", null, m.list), " (entry ", h("code", null, m.entry), ")"]
|
||||
: m.result !== "none" ? ["by your rule for ", h("code", null, ruleName(m.entry)), m.entry.startsWith("*.") ? " (names below it)" : ""] : null))),
|
||||
blocked && writable ? h("p", null, h("button", { class: "small", onclick: () => addRule(name, "allow", false, []) }, "Allow " + name),
|
||||
h("span", { class: "muted small" }, " adds an allow rule for it and the names below it, which beats every list.")) : null);
|
||||
h("ul", { class: "plain" }, res.map((m) => {
|
||||
const rule = ruleById.get(m.rule_id);
|
||||
return h("li", null,
|
||||
m.view ? h("span", { class: "muted" }, "view " + m.view + ": ") : null,
|
||||
m.result === "blocked" ? badge("blocked", "err") : m.result === "allowed" ? badge("allowed", "ok") : badge("not blocked", ""),
|
||||
" ",
|
||||
m.list ? ["by blocklist ", h("strong", null, m.list), " (entry ", h("code", null, m.entry), ")"]
|
||||
: m.result !== "none" ? ["by your rule to ", rule ? rule.action : "", " ", h("code", null, rule ? rule.name : m.entry.replace(/^\*\./, "")), rule && !rule.exact ? " and below" : ""] : null);
|
||||
})),
|
||||
action);
|
||||
}
|
||||
|
||||
const ruleName = (entry) => entry.replace(/^\*\./, "");
|
||||
async function removeRules(list) {
|
||||
try {
|
||||
let r;
|
||||
for (const rule of list) r = await change("DELETE", "/blocking/rules/" + rule.id);
|
||||
toast(describeResult(r));
|
||||
rerender();
|
||||
} catch (e) { toast(e.message, "err", 8000); }
|
||||
}
|
||||
|
||||
async function addRule(name, action, exact, views, comment) {
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user