1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-10 04:06:47 +00:00
webvirtcloud/instances/templates/allinstances_index_grouped.html
catborise 7cf12b997b feat(tables): tables sort with tablesort, the grouped VM list within each host
sortable.js 0.8.0 (abandoned since 2014) sorted only a table's first
body: in the grouped VM list the first host's row moved among its VMs
and the other hosts never sorted, and memory sorted as text ("1024 MB"
before "512 MB"). tablesort 5.7.1 sorts each table body on its own and
keeps a row marked data-sort-method="none" in place, so hosts stay in
name order with their row on top and their VMs sort below it. Memory,
vCPUs and volume sizes sort by their numbers (data-sort). Headers are
reachable by keyboard and carry aria-sort.

base.html loads tablesort for every table marked data-sortable; the
per-page sortable includes and sortable-theme-bootstrap.css go, so these
tables take the theme's table style like the others. The grouped list's
row numbers go (meaningless once sorted). The VM owners and VM logs
tables were marked sortable but never loaded the script; they stay
unsorted.
2026-10-24 19:02:51 +03:00

111 lines
6.5 KiB
HTML

{% load i18n %}
{% load bootstrap_icons %}
<div class="table-responsive">
<table class="table table-hover" data-sortable>
<thead>
<tr>
<th scope="col" data-sort-method="none"><a class="link-primary" href="#" id="hide-all-instances" onclick="hide_all_host_instances()">#</a></th>
<th scope="col">{% trans "Name" %}<br>{% trans "Description" %}</th>
<th scope="col" class="d-none d-sm-table-cell">{% trans "User"%}</th>
<th scope="col">{% trans "Status" %}</th>
{% if app_settings.VM_DRBD_STATUS == 'True' %}
<th scope="col">{% trans "Role/Disk" %}</th>
{% endif %}
<th scope="col" class="d-none d-sm-table-cell" data-sort-method="number">{% trans "VCPU" %}</th>
<th scope="col" class="d-none d-sm-table-cell" data-sort-method="number">{% trans "Memory" %}</th>
<th scope="col" style="width:200px;" data-sort-method="none">{% trans "Actions" %} & {% trans "Mem Usage" %}</th>
</tr>
</thead>
{% for compute in computes %}
<tbody class="searchable" data-host="{{ compute.name }}">
{% if compute.instance_set.count > 0 %}
<tr class="table-secondary fw-bold border-bottom border-dark" data-sort-method="none">
<td>
<span id="collapse_host_instances_{{ compute.id }}" onclick="hide_host_instances('{{ compute.id }}');" class="bi bi-chevron-up" ></span>
</td>
<td>
<a class="link-dark" href="{% url 'overview' compute.id %}">{{ compute.name }}</a>
<span id="inst_count_badge_{{ compute.id }}" class="badge bg-secondary d-none">{{ compute.instance_set.count }}</span>
</td>
<td class="d-none d-sm-table-cell"></td>
<td>
{% if compute.status is True %}
<span class="badge bg-success-subtle text-success-emphasis">{% trans "Connected" %}</span>
{% else %}
<span class="badge bg-danger-subtle text-danger-emphasis">{% trans "Not Connected" %}</span>
{% endif %}
</td>
{% if app_settings.VM_DRBD_STATUS == 'True' %}
<td class="d-none d-sm-table-cell"></td>
{% endif %}
{% if compute.status is True %}
<td class="d-none d-sm-table-cell text-center">{{ compute.cpu_count }}</td>
<td class="d-none d-sm-table-cell text-right">{{ compute.ram_size|filesizeformat }}</td>
<td>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" aria-label="{% trans "Mem Usage" %}" style="width: {{ compute.ram_usage }}%"
aria-valuenow="{{ compute.ram_usage }}" aria-valuemin="0" aria-valuemax="100">{{ compute.ram_usage }}%
</div>
</div>
</td>
{% else %}
<td class="d-none d-sm-table-cell"></td>
<td class="d-none d-sm-table-cell"></td>
<td></td>
{% endif %}
</tr>
{% for instance in compute.instance_set.all %}
<tr host="{{ compute.id }}">
<td></td>
<td>
<a class="link-primary" href="{% url 'instances:instance' instance.id %}">{{ instance.name }}</a>
<br>
{% if instance.info %}<p class="m-0 small fst-italic">{{ instance.title }}</p>{% endif %}
</td>
<td>
<em>
{% if instance.userinstance_set.all.count > 0 %}
{{ instance.userinstance_set.all.0.user }}
{% if instance.userinstance_set.all.count > 1 %}
(+{{ instance.userinstance_set.all.count|add:"-1" }})
{% endif %}
{% endif %}
</em>
</td>
<td>
{% include 'instance_state.html' %}
</td>
{% if app_settings.VM_DRBD_STATUS == 'True' %}
<td>
{% if instance.drbd == "Primary/OK" or instance.drbd == "Secondary/OK" %}<span class="badge bg-success-subtle text-success-emphasis">{% else %}<span class="badge bg-danger-subtle text-danger-emphasis">{% endif %}{{ instance.drbd }}</span>
</td>
{% endif %}
<td data-sort="{{ instance.info.3 }}">{{ instance.info.3 }}</td>
<td data-sort="{{ instance.info.2 }}">{% if instance.info %}{% widthratio instance.info.2 1024 1 %} MB{% endif %}</td>
<td class="text-nowrap">
{% include 'instance_actions.html' %}
</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
{% endfor %}
</table>
</div>
{% block script %}
<script>
// a collapsed host's VM rows are hidden by its table body's class, so the
// search (instance_filter.js, the hidden attribute) can still hide them too
function hide_all_host_instances() {
$('tbody.searchable').toggleClass('host-collapsed');
$('span[id^=collapse_host_instances_]').toggleClass("bi bi-chevron-down ").toggleClass("bi bi-chevron-up");
$('span[id^=inst_count_badge_]').toggleClass("d-none");
}
function hide_host_instances(host) {
$("span[id='collapse_host_instances_"+host+"']").closest('tbody').toggleClass('host-collapsed');
$("span[id='collapse_host_instances_"+host+"']").toggleClass("bi bi-chevron-down ").toggleClass("bi bi-chevron-up");
$("span[id='inst_count_badge_"+host+"']").toggleClass("d-none");
}
</script>
{% endblock %}