From 78c9b3349d3ab43298ab790002bee5f495b91caa Mon Sep 17 00:00:00 2001 From: trisua Date: Tue, 8 Jul 2025 15:21:57 -0400 Subject: [PATCH] add: better domain editor ui --- .../src/public/html/littleweb/browser.lisp | 3 +- .../app/src/public/html/littleweb/domain.lisp | 73 +++++------ .../src/public/html/littleweb/service.lisp | 115 +++++++++++------- crates/core/src/model/littleweb.rs | 3 +- 4 files changed, 112 insertions(+), 82 deletions(-) diff --git a/crates/app/src/public/html/littleweb/browser.lisp b/crates/app/src/public/html/littleweb/browser.lisp index 76ac82b..6da038f 100644 --- a/crates/app/src/public/html/littleweb/browser.lisp +++ b/crates/app/src/public/html/littleweb/browser.lisp @@ -91,6 +91,7 @@ position: fixed; width: calc(100dvw - (62px + var(--pad-2) * 2)) !important; left: var(--pad-2); + z-index: 2; } } @@ -101,7 +102,7 @@ height: var(--h); min-height: var(--h); max-height: var(--h); - font-size: 14px; + font-size: 16px; } #panel button:not(.inner *), diff --git a/crates/app/src/public/html/littleweb/domain.lisp b/crates/app/src/public/html/littleweb/domain.lisp index d8b01f1..96d2da7 100644 --- a/crates/app/src/public/html/littleweb/domain.lisp +++ b/crates/app/src/public/html/littleweb/domain.lisp @@ -72,7 +72,7 @@ ("class" "card hidden w-full lowered flex flex-col gap-2") ("onsubmit" "add_data_from_form(event)") (div - ("class" "flex gap-2") + ("class" "flex gap-2 flex-collapse") (div ("class" "flex w-full flex-col gap-1") (label @@ -119,44 +119,47 @@ (icon (text "check")) (str (text "general:action.save"))))) ; data - (table - (thead - (tr - (th (text "Name")) - (th (text "Type")) - (th (text "Value")) - (th (text "Actions")))) + (div + ("class" "w-full") + ("style" "max-width: 100%; overflow: auto") + (table + (thead + (tr + (th (text "Name")) + (th (text "Type")) + (th (text "Value")) + (th (text "Actions")))) - (tbody - (text "{% for item in domain.data -%}") - (tr - (td (text "{{ item[0] }}")) - (text "{% for k,v in item[1] -%}") - (td (text "{{ k }}")) - (td (text "{{ v }}")) - (text "{%- endfor %}") - (td - ("style" "overflow: auto") - (div - ("class" "dropdown") - (button - ("class" "camo small") - ("onclick" "trigger('atto::hooks::dropdown', [event])") - ("exclude" "dropdown") - (icon (text "ellipsis"))) + (tbody + (text "{% for item in domain.data -%}") + (tr + (td (text "{{ item[0] }}")) + (text "{% for k,v in item[1] -%}") + (td (text "{{ k }}")) + (td (text "{{ v }}")) + (text "{%- endfor %}") + (td + ("style" "overflow: auto") (div - ("class" "inner") + ("class" "dropdown") (button - ("onclick" "rename_data('{{ item[0] }}')") - (icon (text "pencil")) - (str (text "littleweb:action.rename"))) + ("class" "camo small") + ("onclick" "trigger('atto::hooks::dropdown', [event])") + ("exclude" "dropdown") + (icon (text "ellipsis"))) + (div + ("class" "inner") + (button + ("onclick" "rename_data('{{ item[0] }}')") + (icon (text "pencil")) + (str (text "littleweb:action.rename"))) - (button - ("class" "red") - ("onclick" "remove_data('{{ item[0] }}')") - (icon (text "trash")) - (str (text "general:action.delete"))))))) - (text "{%- endfor %}")))))) + (button + ("class" "red") + ("onclick" "remove_data('{{ item[0] }}')") + (icon (text "trash")) + (str (text "general:action.delete"))))))) + (text "{%- endfor %}"))))))) (script ("id" "domain_data") ("type" "application/json") (text "{{ domain.data|json_encode()|safe }}")) (script diff --git a/crates/app/src/public/html/littleweb/service.lisp b/crates/app/src/public/html/littleweb/service.lisp index b0b7ac9..8ef12e1 100644 --- a/crates/app/src/public/html/littleweb/service.lisp +++ b/crates/app/src/public/html/littleweb/service.lisp @@ -14,9 +14,24 @@ (div ("class" "card-nest") (div - ("class" "card small") - (b - (text "{{ service.name }}"))) + ("class" "card small flex flex-col gap-2") + (div + ("class" "flex w-full gap-2 justify-between") + (b + (text "{{ service.name }}")) + + (button + ("class" "small lowered") + ("title" "Help") + ("onclick" "document.getElementById('site_help').classList.toggle('hidden')") + (icon (text "circle-question-mark")))) + + (div + ("class" "card w-full lowered flex flex-col gap-2 hidden no_p_margin") + ("id" "site_help") + (p (text "Your site should include an \"index.html\" file in order to show content on its homepage.")) + (p (text "In the HTML editor, you can type `!` and use the provided suggestion to get an HTML boilerplate.")) + (p (text "After you've created a page, you can click \"Copy ID\" and go to manage a domain you own. On the domain management page, click \"Add\" and paste the ID you copied into the value field.")))) (div ("class" "flex gap-2 flex-wrap card") @@ -72,53 +87,56 @@ ("class" "card flex flex-col gap-2") (text "{% if not file or file.children|length > 0 -%}") ; directory browser - (table - (thead - (tr - (th (text "Name")) - (th (text "Type")) - (th (text "Children")) - (th (text "Actions")))) + (div + ("class" "w-full") + ("style" "max-width: 100%; overflow: auto") + (table + (thead + (tr + (th (text "Name")) + (th (text "Type")) + (th (text "Children")) + (th (text "Actions")))) - (tbody - (text "{% for item in files %}") - (tr - (td - ("class" "flex gap-2 items-center") - (text "{% if item.children|length > 0 -%}") - (icon (text "folder")) - (text "{% else %}") - (icon (text "file")) - (text "{%- endif %}") + (tbody + (text "{% for item in files %}") + (tr + (td + ("class" "flex gap-2 items-center") + (text "{% if item.children|length > 0 -%}") + (icon (text "folder")) + (text "{% else %}") + (icon (text "file")) + (text "{%- endif %}") - (a - ("href" "?path={{ path }}/{{ item.name }}") - ("data-turbo" "false") - (text "{{ item.name }}"))) - (td (text "{{ item.mime }}")) - (td (text "{{ item.children|length }}")) - (td - ("style" "overflow: auto") - (div - ("class" "dropdown") - (button - ("class" "camo small") - ("onclick" "trigger('atto::hooks::dropdown', [event])") - ("exclude" "dropdown") - (icon (text "ellipsis"))) + (a + ("href" "?path={{ path }}/{{ item.name }}") + ("data-turbo" "false") + (text "{{ item.name }}"))) + (td (text "{{ item.mime }}")) + (td (text "{{ item.children|length }}")) + (td + ("style" "overflow: auto") (div - ("class" "inner") + ("class" "dropdown") (button - ("onclick" "rename_file('{{ item.id }}')") - (icon (text "pencil")) - (str (text "littleweb:action.rename"))) + ("class" "camo small") + ("onclick" "trigger('atto::hooks::dropdown', [event])") + ("exclude" "dropdown") + (icon (text "ellipsis"))) + (div + ("class" "inner") + (button + ("onclick" "rename_file('{{ item.id }}')") + (icon (text "pencil")) + (str (text "littleweb:action.rename"))) - (button - ("class" "red") - ("onclick" "remove_file('{{ item.id }}')") - (icon (text "trash")) - (str (text "general:action.delete"))))))) - (text "{% endfor %}"))) + (button + ("class" "red") + ("onclick" "remove_file('{{ item.id }}')") + (icon (text "trash")) + (str (text "general:action.delete"))))))) + (text "{% endfor %}")))) (text "{% else %}") ; file editor (div ("id" "editor_container") ("class" "w-full") ("style" "height: 600px")) @@ -319,6 +337,7 @@ (text "{% if file and file.mime != 'Plain' -%}") (script ("src" "https://unpkg.com/monaco-editor@0.52.2/min/vs/loader.js")) +(script ("src" "https://unpkg.com/emmet-monaco-es/dist/emmet-monaco.min.js")) (script ("id" "file_content") ("type" "text/plain") (text "{{ file.content|remove_script_tags|safe }}")) (script (text "require.config({ paths: { vs: \"https://unpkg.com/monaco-editor@0.52.2/min/vs\" } }); @@ -337,10 +356,16 @@ style.innerText = '@import \"https://unpkg.com/monaco-editor@0.52.2/min/vs/editor/editor.main.css\";'; shadow.appendChild(style); + emmetMonaco.emmetHTML(); + emmetMonaco.emmetCSS(); + globalThis.editor = monaco.editor.create(inner, { value: document.getElementById(\"file_content\").innerText.replaceAll(\"</script>\", \"\"), language: MIME_MODES[\"{{ file.mime }}\"], theme: \"vs-dark\", + suggest: { + snippetsPreventQuickSuggestions: false, + }, }); });")) (text "{%- endif %}") diff --git a/crates/core/src/model/littleweb.rs b/crates/core/src/model/littleweb.rs index 479a444..77b8dc6 100644 --- a/crates/core/src/model/littleweb.rs +++ b/crates/core/src/model/littleweb.rs @@ -193,7 +193,8 @@ macro_rules! define_domain_tlds { define_domain_tlds!( Bunny, Tet, Cool, Qwerty, Boy, Girl, Them, Quack, Bark, Meow, Silly, Wow, Neko, Yay, Lol, Love, - Fun, Gay, City, Woah, Clown, Apple, Yaoi, Yuri, World, Wav, Zero, Evil, Dragon, Yum, Site + Fun, Gay, City, Woah, Clown, Apple, Yaoi, Yuri, World, Wav, Zero, Evil, Dragon, Yum, Site, All, + Me, Bug, Slop, Retro, Eye, Neo, Spring ); #[derive(Debug, Clone, Serialize, Deserialize)]