Files
llmgw/internal/web/static/pages.js
T
Ilker ManapandClaude Opus 5.5 1a3f385be4
CI / test (push) Successful in 10m51s
Every setting of a served model from the mirror page, and its replicas per profile
The row of a served model leads to its card, which now changes its context
and longest answer, its cards, its replicas on each profile with a profile
on CPUs to add and its speed beside, stops, starts and restarts it, and
removes it with its files or without. Stopped on the row stops the model
rather than setting its scaling to nothing. The console gains Replicas per
profile, and ctl models shows the counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 09:40:06 +01:00

71 lines
3.0 KiB
JavaScript

// What the pages did in inline handlers, which the Content-Security-Policy
// does not run: a form sent when a choice changes, a confirmation before a
// removal, a field filled from the option chosen, and the live parts of the
// cluster and node pages refreshed only while the tab is in view.
(function () {
document.addEventListener('change', function (e) {
var t = e.target;
if (t.matches && t.matches('[data-autosubmit]') && t.form) {
t.form.submit();
}
if (t.matches && t.matches('[data-suggest-into]') && t.form) {
var f = t.form.elements[t.getAttribute('data-suggest-into')];
var o = t.selectedOptions[0];
if (f && o) { f.value = o.dataset.suggest || ''; }
}
});
document.addEventListener('submit', function (e) {
// The button's own, where a form has several that mean different things.
var b = e.submitter;
var msg = (b && b.getAttribute && b.getAttribute('data-confirm')) ||
(e.target.getAttribute && e.target.getAttribute('data-confirm'));
if (msg && !window.confirm(msg)) { e.preventDefault(); }
});
// A form being filled in is not refreshed away. The live parts of the
// cluster and node pages are swapped whole every few seconds, and a form
// inside one lost what was typed into it, its open choice, its focus:
// filling one in raced the clock. While a field in the refreshing part
// has the focus, or a form in it has been typed into and not sent, it
// waits; sending the form, or leaving the page, ends that.
var edited = [];
document.addEventListener('input', function (e) {
var f = e.target.form || (e.target.closest && e.target.closest('form'));
if (f && edited.indexOf(f) < 0) { edited.push(f); }
});
document.addEventListener('submit', function (e) {
if (!e.defaultPrevented) { edited = []; }
});
function busy(root) {
var a = document.activeElement;
if (a && a !== document.body && root.contains(a) &&
a.matches('input, select, textarea, [contenteditable]')) {
return true;
}
for (var i = 0; i < edited.length; i++) {
if (root.contains(edited[i]) && document.contains(edited[i])) { return true; }
}
return false;
}
// htmx's trigger filters are evaluated JavaScript; this is the same
// "only while visible" without them, and "not while being filled in".
document.addEventListener('htmx:beforeRequest', function (e) {
var elt = e.detail.elt;
if (elt.hasAttribute('data-visible-only') &&
(document.visibilityState !== 'visible' || busy(elt))) {
e.preventDefault();
}
});
// A page that reloads itself (<meta name="llmgw-refresh" content="N">)
// does it on the same terms, rather than by http-equiv, which nothing
// can hold off.
var r = document.querySelector('meta[name="llmgw-refresh"]');
var every = r ? parseInt(r.getAttribute('content'), 10) : 0;
if (every > 0) {
setInterval(function () {
if (document.visibilityState === 'visible' && !busy(document.body)) {
window.location.reload();
}
}, every * 1000);
}
})();