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"]); +});