From 786ae46c7cf18edc03c3143c890cb24b8485e45f Mon Sep 17 00:00:00 2001 From: EMRG Evolution Date: Thu, 20 Aug 2026 19:24:11 +0800 Subject: [PATCH] =?UTF-8?q?emrg:=20GUI=20task=20form=20sandbox=20field=20?= =?UTF-8?q?=E2=80=94=20three-tier=20select=20with=20backend-consistent=20d?= =?UTF-8?q?efault?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rant 2026-08-20T18:06:44: the GUI add/edit task form had no sandbox support although the backend (scheduler task_create/task_update) validates and stores it. Add a sandbox select (workspace-write / read-only / danger-full-access, default workspace-write matching the backend default), prefill in openTaskForm, include it in saveTaskForm payload, plus i18n key and smoke-test coverage (default, edit prefill, payload on create and update). --- emrg/gui/renderer/index.html | 9 +++++++++ emrg/gui/renderer/js/dialogs.js | 3 +++ emrg/gui/renderer/js/i18n.js | 2 ++ emrg/gui/test/renderer.smoke.test.js | 15 ++++++++++++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/emrg/gui/renderer/index.html b/emrg/gui/renderer/index.html index d58f10f..8d98fea 100644 --- a/emrg/gui/renderer/index.html +++ b/emrg/gui/renderer/index.html @@ -107,6 +107,15 @@

任务管理

启用 +
+ +
diff --git a/emrg/gui/renderer/js/dialogs.js b/emrg/gui/renderer/js/dialogs.js index 3874c60..4fa1d42 100644 --- a/emrg/gui/renderer/js/dialogs.js +++ b/emrg/gui/renderer/js/dialogs.js @@ -761,6 +761,8 @@ const Dialogs = (() => { $("task-form-interval").value = task && task.interval != null ? task.interval : 1800; $("task-form-enabled").checked = task ? task.enabled !== false : true; $("task-form-repo").value = cfg.repo || ""; + // rant 2026-08-20T18:06:44:沙箱下拉预填(编辑读 task.sandbox;新增默认 workspace-write 与后端默认一致) + $("task-form-sandbox").value = (task && task.sandbox) || "workspace-write"; $("task-form").classList.remove("hidden"); $("task-form-name").focus(); } @@ -790,6 +792,7 @@ const Dialogs = (() => { interval, enabled: $("task-form-enabled").checked, repo: $("task-form-repo").value.trim() || undefined, + sandbox: $("task-form-sandbox").value, }; try { if (editingTask === null) await window.emrg.taskCreate(payload); diff --git a/emrg/gui/renderer/js/i18n.js b/emrg/gui/renderer/js/i18n.js index 9e01ef7..ae1a8d4 100644 --- a/emrg/gui/renderer/js/i18n.js +++ b/emrg/gui/renderer/js/i18n.js @@ -101,6 +101,7 @@ const I18N = (() => { "settings.taskInterval": "间隔(秒,≥60)", "settings.taskEnabled": "启用", "settings.taskRepo": "仓库(选填 owner/repo)", + "settings.taskSandbox": "沙箱", "settings.taskSave": "保存任务", "settings.taskTrigger": "触发", "settings.taskEdit": "编辑", @@ -509,6 +510,7 @@ const I18N = (() => { "settings.taskInterval": "Interval (sec, ≥60)", "settings.taskEnabled": "Enabled", "settings.taskRepo": "Repo (optional owner/repo)", + "settings.taskSandbox": "Sandbox", "settings.taskSave": "Save task", "settings.taskTrigger": "Trigger", "settings.taskEdit": "Edit", diff --git a/emrg/gui/test/renderer.smoke.test.js b/emrg/gui/test/renderer.smoke.test.js index 2cc8d12..b4c0988 100644 --- a/emrg/gui/test/renderer.smoke.test.js +++ b/emrg/gui/test/renderer.smoke.test.js @@ -154,6 +154,7 @@ const ELEMENT_IDS = [ "task-list", "task-add-btn", "task-template-mgr-btn", "task-form", "task-form-name", "task-form-type", "task-form-project", "task-form-interval", "task-form-enabled", "task-form-repo", + "task-form-sandbox", "task-form-cancel", "task-form-save", "task-template-form", "task-template-name", "task-template-prompt", "task-template-cancel", "task-template-save", "task-template-list", @@ -2525,8 +2526,11 @@ test("P3:设置面板打开 → 任务列表渲染(名称/类型/项目/间 assert.strictEqual(els["task-form-interval"].value, 1800); assert.strictEqual(els["task-form-enabled"].checked, true); assert.strictEqual(els["task-form-repo"].value, ""); + // rant 18:06:44:沙箱下拉默认 workspace-write(与后端默认一致);任务无 sandbox 字段 → 默认值 + assert.strictEqual(els["task-form-sandbox"].value, "workspace-write", "编辑任务默认沙箱档位应为 workspace-write"); // 修改后保存 → taskUpdate vm.runInContext('document.getElementById("task-form-interval").value = "600"', ctx); + vm.runInContext('document.getElementById("task-form-sandbox").value = "read-only"', ctx); await vm.runInContext("EMRG_Dialogs.saveTaskForm()", ctx); await tick(); assert.ok(updated, "taskUpdate 应被调用"); @@ -2535,6 +2539,7 @@ test("P3:设置面板打开 → 任务列表渲染(名称/类型/项目/间 assert.strictEqual(updated.type, "evolution"); assert.strictEqual(updated.project, "emrg"); assert.strictEqual(updated.enabled, true); + assert.strictEqual(updated.sandbox, "read-only", "保存 payload 应含沙箱档位"); }); test("rant 21:32:32:任务卡点击展开最近运行子表(时间/干了什么/降频徽章)", async () => { @@ -2651,7 +2656,7 @@ test("P3:新增任务表单 —— 间隔 <60 客户端拒绝;≥60 提交 t assert.ok((els["confirm-message"].textContent || "").includes("60"), `错误提示含 60:${els["confirm-message"].textContent}`); assert.strictEqual(created, null, "非法间隔不应提交 taskCreate"); await vm.runInContext("EMRG_Dialogs.closeConfirm()", ctx); - // 间隔 600 → 提交(含自定义类型 + 启用勾选) + // 间隔 600 → 提交(含自定义类型 + 启用勾选 + 默认沙箱 workspace-write) vm.runInContext('document.getElementById("task-form-interval").value = "600"', ctx); await vm.runInContext("EMRG_Dialogs.saveTaskForm()", ctx); await tick(); @@ -2661,6 +2666,14 @@ test("P3:新增任务表单 —— 间隔 <60 客户端拒绝;≥60 提交 t assert.strictEqual(created.project, "emrg"); assert.strictEqual(created.interval, 600); assert.strictEqual(created.enabled, true); + assert.strictEqual(created.sandbox, "workspace-write", "新增任务 payload 默认沙箱应为 workspace-write"); + // 下拉切换档位 → payload 跟随 + vm.runInContext('document.getElementById("task-form-name").value = "new-task2"', ctx); + vm.runInContext('document.getElementById("task-form-sandbox").value = "danger-full-access"', ctx); + await vm.runInContext("EMRG_Dialogs.saveTaskForm()", ctx); + await tick(); + assert.strictEqual(created.name, "new-task2"); + assert.strictEqual(created.sandbox, "danger-full-access", "切换档位后 payload 应跟随"); assert.strictEqual(vm.runInContext('document.getElementById("task-form").classList.contains("hidden")', ctx), true, "保存后表单收起"); });