From 0f552f24e72e3aacbb89c0100713ca2cb00e38d7 Mon Sep 17 00:00:00 2001 From: digital-garbage <133010426+digital-garbage@users.noreply.github.com> Date: Tue, 6 Oct 2026 03:28:54 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20an=20unset=20file=20dropdown=20shows=20?= =?UTF-8?q?=E2=80=9Cchoose=E2=80=9D,=20not=20the=20first=20file=20it=20nev?= =?UTF-8?q?er=20saved?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- app/ui/features/settings/models.js | 9 ++++++--- app/ui/features/settings/models.test.js | 11 +++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/ui/features/settings/models.js b/app/ui/features/settings/models.js index 06cb119e..86a5190f 100644 --- a/app/ui/features/settings/models.js +++ b/app/ui/features/settings/models.js @@ -10,9 +10,12 @@ const fed = (v) => Array.isArray(v); export const widgetControl = (w, current, set) => { const label = w.name; if (w.type === "COMBO") { - const choices = [...(w.choices || [])]; - if (current != null && !choices.includes(current)) choices.unshift(current); // a file gone from disk still shows, so saving something else cannot swap it out - return choices.length ? c.select.md({ label, value: current ?? choices[0], options: choices.map((v) => ({ value: v, label: String(v) })), onChange: set }) + const choices = [...(w.choices || [])], unset = current == null || current === ""; + if (!unset && !choices.includes(current)) choices.unshift(current); // a file gone from disk still shows, so saving something else cannot swap it out + // Nothing chosen shows as nothing chosen: showing the first file would look picked while the run has none + // (and with one file there is nothing to change to, so it could never be picked). + const options = [...(unset ? [{ value: "", label: "— choose —" }] : []), ...choices.map((v) => ({ value: v, label: String(v) }))]; + return choices.length ? c.select.md({ label, value: unset ? "" : current, options, onChange: (v) => { if (v !== "") set(v); } }) : c.hint.default({ text: "No choices available — nothing found in the models folder." }); } if (w.type === "INT" || w.type === "FLOAT") { diff --git a/app/ui/features/settings/models.test.js b/app/ui/features/settings/models.test.js index e827419e..1d642874 100644 --- a/app/ui/features/settings/models.test.js +++ b/app/ui/features/settings/models.test.js @@ -34,3 +34,14 @@ test("a node the server says needs something shows the orange dot, whichever way assert.equal(dots.length, 2); assert.ok(dots.every((d) => d.classList.contains("fp-needs"))); }); + +test("a file input nothing has chosen shows “choose”, not the first file, and the one file can be picked", async () => { + const { widgetControl } = await import("./models.js"); + const picked = []; + const ctl = widgetControl({ name: "model_name", type: "COMBO", choices: ["only.safetensors"] }, undefined, (v) => picked.push(v)); + const select = ctl.node.querySelector("select") || ctl.node; + assert.equal(select.value, ""); + select.value = "only.safetensors"; + select.dispatchEvent(new Event("change", { bubbles: true })); + assert.deepEqual(picked, ["only.safetensors"]); +});