From 34ca6804d59c8d7578b1b1fdbb07b35b791d9259 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Tue, 29 Jul 2025 17:23:12 +1000 Subject: [PATCH] Improve look of runtime toggle, and general UI enhancements for editor --- static/js/mithril/editor.js | 140 ++++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 54 deletions(-) diff --git a/static/js/mithril/editor.js b/static/js/mithril/editor.js index 761e1f4..f674e4c 100644 --- a/static/js/mithril/editor.js +++ b/static/js/mithril/editor.js @@ -278,8 +278,7 @@ const Editor = { m( "div", { - class: - "flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-800", + class: "flex items-center justify-between pl-2", }, [ // Left side: name/version OR add input (shown only if showHeader==true) @@ -367,8 +366,84 @@ const Editor = { ]) : m("div"), // If header is hidden, left side is empty - // Right side: always show spinner or execute button - m("div", { class: "flex items-center space-x-3" }, [ + // Right side is now empty as controls are moved down + m("div"), + ] + ), + + /* ───────────────────────────────────────────────────────────────── + AI Generation + ─────────────────────────────────────────────────────────────────*/ + m( + "div", + { + class: + "flex items-center justify-between p-2 border-b border-gray-200 dark:border-gray-800", + }, + [ + // Left side: AI Generation + m("div", {}, [ + m( + "button", + { + class: "text-sm text-blue-500 hover:underline", + onclick: () => + (this.showNaturalLanguageQuery = + !this.showNaturalLanguageQuery), + }, + "Generate with AI" + ), + ]), + + // Right side: Runtime toggle and Execute button + m("div", { class: "flex items-center space-x-4" }, [ + // Runtime Toggle Switch + m( + "label", + { + for: "runtime-toggle", + class: "inline-flex items-center cursor-pointer", + }, + [ + m( + "span", + { + class: + "mr-3 text-sm font-medium " + + (this.runtime === "node" + ? "text-green-500" + : "text-gray-400 dark:text-gray-500"), + }, + "Node" + ), + m("div", { class: "relative" }, [ + m("input[type=checkbox]", { + id: "runtime-toggle", + class: "sr-only peer", + checked: this.runtime === "deno", + onchange: (e) => { + this.runtime = e.target.checked ? "deno" : "node"; + }, + }), + m("div", { + class: + "w-11 h-6 bg-gray-200 rounded-full peer peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600", + }), + ]), + m( + "span", + { + class: + "ml-3 text-sm font-medium " + + (this.runtime === "deno" + ? "text-blue-500" + : "text-gray-400 dark:text-gray-500"), + }, + "Deno" + ), + ] + ), + this.executeLoading ? m("div", { class: @@ -402,22 +477,12 @@ const Editor = { ] ), - /* ───────────────────────────────────────────────────────────────── - AI Generation - ─────────────────────────────────────────────────────────────────*/ - m("div", { class: "p-2 border-b border-gray-200 dark:border-gray-800" }, [ + // AI Generation Text Area (conditionally shown) + this.showNaturalLanguageQuery && m( - "button", - { - class: "text-sm text-blue-500 hover:underline", - onclick: () => - (this.showNaturalLanguageQuery = !this.showNaturalLanguageQuery), - }, - "Generate with AI" - ), - - this.showNaturalLanguageQuery && - m("div", { class: "mt-2" }, [ + "div", + { class: "p-2 border-b border-gray-200 dark:border-gray-800" }, + [ m("textarea", { class: "w-full p-2 border rounded bg-gray-50 dark:bg-gray-700 dark:border-gray-600", @@ -442,8 +507,8 @@ const Editor = { }) : "Generate" ), - ]), - ]), + ] + ), /* ───────────────────────────────────────────────────────────────── JS Editor @@ -520,39 +585,6 @@ const Editor = { m("div", { class: "flex flex-col space-y-4" }, [ // Toggles group m("div", { class: "flex flex-wrap gap-6" }, [ - // Runtime dropdown - m("div", { class: "flex flex-col" }, [ - m( - "label", - { - for: "runtime-select", - class: "mb-2 text-sm font-medium", - }, - "Runtime" - ), - m( - "select", - { - id: "runtime-select", - class: - "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500", - onchange: (e) => (this.runtime = e.target.value), - }, - [ - m( - "option", - { value: "node", selected: this.runtime === "node" }, - "Node.js" - ), - m( - "option", - { value: "deno", selected: this.runtime === "deno" }, - "Deno" - ), - ] - ), - ]), - // Public/Private toggle this.showPublicToggle && m(