1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-10 12:16:49 +00:00

feat(instances): the VM list filters by state, and a host's name finds its VMs

The list gets a state selector beside the search box. The search now
matches plain text in any case (a '(' no longer breaks it), and in the
grouped list a host's name shows all of its VMs while a host row shows
only while one of its VMs does. The filter moves to
static/js/instance_filter.js with a Node test; the other lists keep
filter-table.js. Collapsing a host now sets a class on its table body
instead of each row's display, so a collapsed host and the filter no
longer undo each other.
This commit is contained in:
catborise 2026-10-24 16:48:41 +03:00
parent 70e5c317ff
commit 47fadea53c
10 changed files with 152 additions and 11 deletions

View file

@ -53,6 +53,10 @@ body {
height: 350px;
}
.host-collapsed tr[host] {
display: none;
}
.search {
margin: 5px;
}

View file

@ -0,0 +1,43 @@
// The instance list's search box and state list.
//
// A VM row shows when its text contains the search, in any case, and the VM is
// in the chosen state. In the grouped list a search for a host's name shows
// all of its VMs, and the host's row shows while any of its VMs does.
function filterInstances(doc) {
var text = doc.getElementById("filter").value.toLowerCase();
var state = doc.getElementById("state-filter").value;
doc.querySelectorAll(".searchable").forEach(function (group) {
var host = group.dataset.host;
var hostMatches = host !== undefined && host.toLowerCase().includes(text);
var header = null, shown = false;
group.querySelectorAll("tr").forEach(function (row) {
var mark = row.querySelector("[data-state]");
if (!mark) {
header = row;
return;
}
row.hidden = !((!state || mark.dataset.state === state) &&
(hostMatches || row.textContent.toLowerCase().includes(text)));
shown = shown || !row.hidden;
});
if (header) {
header.hidden = !shown;
}
});
}
if (typeof module !== "undefined") {
module.exports = {filterInstances: filterInstances};
} else {
// the search is remembered for a day, as on the other lists
var search = document.getElementById("filter");
search.value = Cookies.get(document.title + "_filter") || "";
search.addEventListener("input", function () {
Cookies.set(document.title + "_filter", search.value, {expires: 1});
filterInstances(document);
});
document.getElementById("state-filter").addEventListener("change", function () {
filterInstances(document);
});
filterInstances(document);
}