You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by gs...@apache.org on 2026/10/12 03:33:33 UTC
(tooling-llmao) 02/08: models: copy the model id from an icon, not a "Copy" link
This is an automated email from the ASF dual-hosted git repository.
gstein pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-llmao.git
commit 28a84862410b8be50d9da5c350e020664287b97d
Author: Greg Stein <gs...@gmail.com>
AuthorDate: Sun Oct 11 21:33:35 2026 -0500
models: copy the model id from an icon, not a "Copy" link
The word sat on the card's heading line beside the name and the id and
read as a third piece of text. It is now a clipboard icon with a title
and a matching aria-label, and turns into a check mark for a moment
when the copy succeeds.
Co-authored-by: Claude Opus 5.5 <no...@anthropic.com>
---
static/css/llmao.css | 12 ++++++++++++
static/js/llmao.js | 12 ++++++++++--
templates/models.ezt | 7 ++++---
tests/test_pages_models.py | 14 ++++++++++++++
4 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/static/css/llmao.css b/static/css/llmao.css
index 543f02b..d092263 100644
--- a/static/css/llmao.css
+++ b/static/css/llmao.css
@@ -28,6 +28,18 @@ body {
.models-page .model-id {
font-size: 0.85rem;
}
+/* An icon, not a link: muted until it is pointed at. */
+.models-page .model-copy {
+ color: var(--bs-secondary-color);
+ line-height: 1;
+}
+.models-page .model-copy:hover,
+.models-page .model-copy:focus-visible {
+ color: var(--bs-body-color);
+}
+.models-page .model-copy.model-copy-done {
+ color: var(--bs-success);
+}
/* Privacy is a full sentence in its own block. Color only reinforces it. */
.models-page .model-privacy {
display: flex;
diff --git a/static/js/llmao.js b/static/js/llmao.js
index b5d01c1..e627319 100644
--- a/static/js/llmao.js
+++ b/static/js/llmao.js
@@ -66,10 +66,18 @@ document.addEventListener("DOMContentLoaded", function () {
btn.addEventListener("click", function () {
var text = btn.getAttribute("data-copy") || "";
if (!text || !navigator.clipboard) return;
+ var icon = btn.querySelector(".bi");
+ var label = btn.getAttribute("title") || "";
navigator.clipboard.writeText(text).then(function () {
- btn.textContent = "Copied";
+ if (icon) icon.className = "bi bi-check-lg";
+ btn.classList.add("model-copy-done");
+ btn.setAttribute("title", "Copied");
+ btn.setAttribute("aria-label", "Copied");
setTimeout(function () {
- btn.textContent = "Copy";
+ if (icon) icon.className = "bi bi-clipboard";
+ btn.classList.remove("model-copy-done");
+ btn.setAttribute("title", label);
+ btn.setAttribute("aria-label", label);
}, 1500);
});
});
diff --git a/templates/models.ezt b/templates/models.ezt
index fb749cb..50ea739 100644
--- a/templates/models.ezt
+++ b/templates/models.ezt
@@ -72,9 +72,10 @@
<div class="d-flex align-items-baseline flex-wrap gap-2">
<h2 class="h5 mb-0">[models.display_name]</h2>
<code class="model-id">[models.model_name]</code>
- <button type="button" class="btn btn-link btn-sm p-0 js-copy-model"
- aria-label="Copy the ID [models.model_name]"
- data-copy="[models.model_name]">Copy</button>
+ <button type="button" class="btn btn-link btn-sm p-0 model-copy js-copy-model"
+ title="Copy [models.model_name] to the clipboard"
+ aria-label="Copy [models.model_name] to the clipboard"
+ data-copy="[models.model_name]"><i class="bi bi-clipboard" aria-hidden="true"></i></button>
</div>
[if-any models.privacy]
<div class="model-privacy model-privacy-[models.privacy_key] mt-2">
diff --git a/tests/test_pages_models.py b/tests/test_pages_models.py
index 69e6b3f..b0fb0a5 100644
--- a/tests/test_pages_models.py
+++ b/tests/test_pages_models.py
@@ -515,6 +515,20 @@ def test_every_state_has_a_badge_class():
assert pages._badge_class(HEALTHY, routed=False) == "text-bg-warning"
+def test_card_copies_the_model_id_from_an_icon():
+ pages = _app()
+ rows = pages.model_catalog_rows(_fleet(_server("gemma")), [_catalog("gemma")])
+ out = _render(rows)
+ button = out[out.index("js-copy-model") :]
+ button = button[: button.index("</button>")]
+ assert 'title="Copy gemma to the clipboard"' in button
+ assert 'aria-label="Copy gemma to the clipboard"' in button
+ assert 'data-copy="gemma"' in button
+ assert "bi-clipboard" in button
+ # The icon is the whole content; the name is in the attributes.
+ assert button.rstrip().endswith("</i>")
+
+
def test_mixed_card_and_unavailable_card():
pages = _app()
box = _server("gemma")
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org