mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-10 12:16:49 +00:00
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.
98 lines
4.3 KiB
HTML
98 lines
4.3 KiB
HTML
{% extends "base.html" %}
|
|
{% load i18n %}
|
|
{% load static %}
|
|
{% block title %}{% trans "Instances" %}{% endblock %}
|
|
{% block style %}
|
|
<link rel="stylesheet" href="{% static 'css/sortable-theme-bootstrap.css' %}" />
|
|
{% endblock %}
|
|
{% block page_heading %}{% trans "Instances" %}{% endblock page_heading %}
|
|
|
|
{% block page_heading_extra %}
|
|
{% if request.user.is_superuser %}
|
|
{% include 'create_inst_block.html' %}
|
|
{% endif %}
|
|
{% include 'search_block.html' %}
|
|
<div class="float-end search">
|
|
<select id="state-filter" class="form-select" aria-label="{% trans 'State' %}">
|
|
<option value="">{% trans 'All states' %}</option>
|
|
{% for state in states %}
|
|
<option>{{ state }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
{% endblock page_heading_extra %}
|
|
|
|
{% block content %}
|
|
{% if show_hosts %}
|
|
{% for compute in computes %}
|
|
{% if compute.status is not True %}
|
|
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
|
{% trans 'Problem occurred with host' %} {{ compute.name }}: {{ compute.connection_error }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% elif own_hosts_down %}
|
|
<div class="alert alert-warning alert-dismissible fade show" role="alert">
|
|
{% trans 'A host of some of your virtual machines cannot be reached right now.' %}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
{% endif %}
|
|
<div class="col-lg-12">
|
|
{% if app_settings.VIEW_INSTANCES_LIST_STYLE == 'grouped' and request.user.is_superuser %}
|
|
{% include 'allinstances_index_grouped.html' %}
|
|
{% else %}
|
|
{% include 'allinstances_index_nongrouped.html' %}
|
|
{% endif %}
|
|
</div>
|
|
{% endblock content %}
|
|
{% block script %}
|
|
<script src="{% static 'js/sortable.min.js' %}"></script>
|
|
<script src="{% static 'js/instance_filter.js' %}"></script>
|
|
{% if request.user.is_superuser %}
|
|
<script>
|
|
// The new-VM dialog's CPU bars: each compute's load over one second,
|
|
// read when the dialog opens, two computes at a time (each read holds
|
|
// a worker for that second). Answers of an earlier opening are ignored.
|
|
const addInstance = document.getElementById("AddInstance");
|
|
let cpuOpening = 0, cpuQueue = [], cpuReading = 0;
|
|
|
|
function setCpuUsage(cell, percent, text) {
|
|
const meter = cell.querySelector(".progress");
|
|
cell.querySelector(".progress-bar").style.width = (percent || 0) + "%";
|
|
if (percent === null) {
|
|
meter.removeAttribute("aria-valuenow");
|
|
} else {
|
|
meter.setAttribute("aria-valuenow", percent);
|
|
}
|
|
cell.querySelector(".cpu-usage-value").textContent = text;
|
|
}
|
|
|
|
function readCpuUsage() {
|
|
while (cpuReading < 2 && cpuQueue.length) {
|
|
const cell = cpuQueue.shift(), opening = cpuOpening;
|
|
const show = (percent, text) => { if (opening === cpuOpening) setCpuUsage(cell, percent, text); };
|
|
cpuReading++;
|
|
$.getJSON(cell.dataset.url)
|
|
.done((data) => {
|
|
const usage = typeof data.cpudata === "number" ? Math.round(data.cpudata) : null;
|
|
show(usage, usage === null ? "—" : usage + "%");
|
|
})
|
|
.fail(() => show(null, "—"))
|
|
.always(() => { cpuReading--; readCpuUsage(); });
|
|
}
|
|
}
|
|
|
|
addInstance.addEventListener("show.bs.modal", function () {
|
|
cpuOpening++;
|
|
cpuQueue = Array.from(addInstance.querySelectorAll(".cpu-usage"));
|
|
cpuQueue.forEach((cell) => setCpuUsage(cell, null, "…"));
|
|
readCpuUsage();
|
|
});
|
|
addInstance.addEventListener("hide.bs.modal", function () {
|
|
cpuOpening++;
|
|
cpuQueue = [];
|
|
});
|
|
</script>
|
|
{% endif %}
|
|
{% endblock script %}
|