Move a rule several places in one change

The Rules page has a Move… button that puts a rule before any other of
its chain, or at the end, in one move. Staged in a changeset, a move
right after a move of the same object takes its place, so pressing ↑
three times is one operation; moving it back where it was takes the
operation out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-25 01:33:37 +01:00
1 parent 57ab9881db
commit 5348765d90
6 files changed
+129 -3

No files matched your search

+23
View File
@@ -62,6 +62,7 @@ export async function render(el, params, query) {
return [
h("button", { class: "small reveal", title: "Move up", disabled: i === 0, onclick: () => move(r, { before: rs[i - 1].id }) }, "↑"), " ",
h("button", { class: "small reveal", title: "Move down", disabled: i === rs.length - 1, onclick: () => move(r, { after: rs[i + 1].id }) }, "↓"), " ",
h("button", { class: "small reveal", title: "Move to another place, in one change", disabled: rs.length < 2, onclick: () => moveDialog(r, rs, (x) => live(rules).indexOf(x) + 1) }, "Move…"), " ",
h("button", { class: "small reveal", onclick: () => ruleDialog(r, chain) }, "Edit"), " ",
h("button", { class: "small reveal", onclick: () => toggle(r) }, r.disabled ? "Enable" : "Disable"), " ",
h("button", { class: "small reveal", onclick: () => del(r) }, "Delete"),
@@ -245,6 +246,28 @@ async function move(r, where) {
try { await change("POST", "/rules/" + r.id + "/move", where, { quiet: true }); rerender(); } catch (e) { modal("Not moved", errorBox(e)); }
}
// moveDialog puts a rule anywhere among rs (the rules it can move
// among) in one move: one change, or one staged operation.
async function moveDialog(r, rs, order) {
const others = rs.filter((x) => x !== r);
const label = (x) => order(x) + ". " + (x.comment || (x.raw ? x.raw : describe(x))) + " (#" + x.id + ")";
const next = rs[rs.indexOf(r) + 1];
const where = select([...others.map((x) => [String(x.id), "before " + label(x)]), ["end", "after " + label(others[others.length - 1])]],
next ? String(next.id) : "end");
const err = h("div");
await modal("Move " + (r.comment || "rule #" + r.id), h("div", null, h("div", { class: "form-grid" }, field("Put it", where)), err), [
{ label: "Cancel", value: null },
{ label: "Move", kind: "primary", onclick: async () => {
const v = where.value;
if (v === (next ? String(next.id) : "end")) return true; // where it is
try {
await change("POST", "/rules/" + r.id + "/move", v === "end" ? { after: others[others.length - 1].id } : { before: Number(v) }, { quiet: true });
rerender();
} catch (e) { mount(err, errorBox(e)); return false; }
} },
]);
}
async function toggle(r) {
try { await change("PATCH", "/rules/" + r.id, { disabled: !r.disabled }); rerender(); } catch (e) { modal("Not changed", errorBox(e)); }
}