Split the model admin into a list and a page per model
/admin/models rendered a full edit form for every model. With eight that
was merely long; with a hundred it was unusable, which is the report.
The list is now compact rows only -- avatar, name, badges, position,
reorder buttons, Edit link -- with search across id and display name,
filter tabs (All / Enabled / Disabled / Pinned / Restricted, each with a
count), a connection filter, and pagination at 40. Filters are links, so
a filtered view is a real URL you can keep. Editing moved to
/admin/models/{id}/edit, one model per page, with Previous/Next links so
a freshly imported connection can be tidied without returning to the
list each time.
Measured with 128 models: the list is 73 KB showing 40 rows over 4
pages, and a detail page is 17 KB. The old page would have rendered all
128 forms into one response.
Reordering needed rethinking at that size too. Up/down is fine for
nudging a model one place but hopeless for moving it sixty, so the
detail page has a position field you type into; the value is clamped and
a non-numeric one is ignored rather than throwing. The move buttons take
a `back` field so they return to whatever filtered, paginated view they
were pressed on instead of dumping you at page 1.
Also adds a select-all checkbox for the bulk bar, scoped to a container
selector rather than the page so a future list can carry more than one.
212 tests, ruff clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -232,6 +232,18 @@
|
||||
if (event.target.matches("[data-autosize]")) autosize(event.target);
|
||||
});
|
||||
|
||||
/* A "select all" box driving every checkbox inside a container. Scoped to a
|
||||
selector rather than the whole page, so a list can carry more than one. */
|
||||
document.addEventListener("change", function (event) {
|
||||
var master = event.target.closest("[data-select-all]");
|
||||
if (!master) return;
|
||||
var scope = document.querySelector(master.dataset.selectAll);
|
||||
if (!scope) return;
|
||||
scope.querySelectorAll('input[type="checkbox"]').forEach(function (box) {
|
||||
box.checked = master.checked;
|
||||
});
|
||||
});
|
||||
|
||||
/* Enter sends, Shift+Enter inserts a newline -- the convention every chat
|
||||
application uses. Left alone on touch devices, where there is no easy
|
||||
Shift and Enter should mean "new line". */
|
||||
|
||||
Reference in New Issue
Block a user