mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
- The state filter is a row of pills, All and each state, counting the VMs the search finds (the chosen state aside); a state without any is hidden unless chosen (All never), and a status line tells screen readers how many VMs match. Every state keeps its pill. - A labelled "New VM" button replaces the bare green plus; "Find IP" says "Find IP / MAC", which it finds. - States are badges; a shut-off VM is grey, not red: it is not a fault. - A VM's cell holds its name, its title, and for those who see owners its first owner as a badge, "+N" for the others (named for screen readers and on hover); the separate user column goes. - Each row has the same button group for a superuser or the VM's owners, from the actions the user may use (states.allowed_actions), all of it disabled on a VM an administrator paused; view-only users get none. It holds Console, the power action the state calls for (Start, Resume, Shut down, or Clone for a template) and a menu of the others (Suspend, Force off, Power cycle), what does not apply now disabled. The power button is an icon, named on hover and for screen readers, so every group is as wide and they line up from row to row; the power cut confirmations stay. On a phone Console shows its icon only too. - A grouped host's row has its name, a Connected or Not connected badge, its VM count and a labelled host memory bar; an unreachable host's row is table-warning. Its collapse control and the one for all hosts are buttons, with aria-expanded kept. - vCPUs and memory hide on a phone in both layouts, and table cells keep Bootstrap's own padding there: Zephyr doubles it and a list's last column no longer fit the screen.
65 lines
5 KiB
HTML
65 lines
5 KiB
HTML
{% load i18n %}
|
|
{% load bootstrap_icons %}
|
|
{% load vm_states %}
|
|
{# the actions this user may use on the VM now (states.allowed_actions), as one group of the same shape in every row: the console, the power action the state calls for (its icon only, named on hover), and a menu of the others; what does not apply now is disabled, all of it for a VM its owner cannot use now (one an administrator paused). The console's word is hidden on a phone. #}
|
|
{% vm_actions instance as actions %}
|
|
{% vm_manages instance as manages %}
|
|
{% if actions or manages and instance.info %}
|
|
<div class="d-flex justify-content-end">
|
|
<div class="btn-group" role="group" aria-label="{% blocktrans with name=instance.name %}Actions for {{ name }}{% endblocktrans %}">
|
|
<button class="btn btn-sm btn-outline-secondary" type="button" data-url="{% url 'console' instance.compute_id instance.uuid %}" data-window="console-{{ instance.uuid }}"
|
|
onclick="window.open(this.dataset.url, this.dataset.window, 'width=850,height=650')" aria-label="{% trans "Console" %}"{% if "console" not in actions %} disabled{% endif %}>{% bs_icon 'display' %} <span class="d-none d-sm-inline">{% trans "Console" %}</span></button>
|
|
{% if "clone" in actions %}
|
|
<a href="{% url 'instances:instance' instance.id %}#clone" class="btn btn-sm btn-outline-secondary" title="{% trans "Clone" %}" aria-label="{% trans "Clone" %}">{% bs_icon 'copy' %}</a>
|
|
{% elif "poweron" in actions %}
|
|
<form action="{% url 'instances:poweron' instance.id %}" method="post" class="btn-group" onsubmit="showPleaseWaitDialog()">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-outline-secondary" title="{% trans "Start" %}" aria-label="{% trans "Start" %}">{% bs_icon 'play-fill' %}</button>
|
|
</form>
|
|
{% elif "resume" in actions %}
|
|
<form action="{% url 'instances:resume' instance.id %}" method="post" class="btn-group">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-outline-secondary" title="{% trans "Resume" %}" aria-label="{% trans "Resume" %}">{% bs_icon 'play-fill' %}</button>
|
|
</form>
|
|
{% elif "poweroff" in actions %}
|
|
<form action="{% url 'instances:poweroff' instance.id %}" method="post" class="btn-group">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-outline-secondary" title="{% trans "Shut down" %}" aria-label="{% trans "Shut down" %}">{% bs_icon 'stop-fill' %}</button>
|
|
</form>
|
|
{% else %}
|
|
{% if instance.info.0 == 3 %}
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" title="{% trans "Resume" %}" aria-label="{% trans "Resume" %}" disabled>{% bs_icon 'play-fill' %}</button>
|
|
{% else %}
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" title="{% trans "Start" %}" aria-label="{% trans "Start" %}" disabled>{% bs_icon 'play-fill' %}</button>
|
|
{% endif %}
|
|
{% endif %}
|
|
<div class="btn-group">
|
|
{# fixed: the menu would be cut off by the table's scrolling box #}
|
|
<button class="btn btn-sm btn-outline-secondary" type="button" data-bs-toggle="dropdown" aria-expanded="false"
|
|
data-bs-popper-config='{"strategy": "fixed"}' aria-label="{% trans "More actions" %}"
|
|
{% if "suspend" not in actions and "force_off" not in actions and "powercycle" not in actions %}disabled{% endif %}>{% bs_icon 'three-dots' %}</button>
|
|
<ul class="dropdown-menu dropdown-menu-end shadow">
|
|
{% if "suspend" in actions %}
|
|
<li><form action="{% url 'instances:suspend' instance.id %}" method="post">{% csrf_token %}
|
|
<button type="submit" class="dropdown-item">{% bs_icon 'pause-fill' %} {% trans "Suspend" %}</button>
|
|
</form></li>
|
|
{% endif %}
|
|
{% if "force_off" in actions %}
|
|
<li><form action="{% url 'instances:force_off' instance.id %}" method="post">{% csrf_token %}
|
|
<button type="submit" class="dropdown-item text-danger"
|
|
data-confirm="{% blocktrans with name=instance.name %}Force off {{ name }}? It stops at once, as after a power cut; what the guest has not written to disk is lost.{% endblocktrans %}"
|
|
onclick="return confirm(this.dataset.confirm)">{% bs_icon 'power' %} {% trans "Force off" %}</button>
|
|
</form></li>
|
|
{% endif %}
|
|
{% if "powercycle" in actions %}
|
|
<li><form action="{% url 'instances:powercycle' instance.id %}" method="post">{% csrf_token %}
|
|
<button type="submit" class="dropdown-item text-danger"
|
|
data-confirm="{% blocktrans with name=instance.name %}Power cycle {{ name }}? It stops at once, as after a power cut, and starts again; what the guest has not written to disk is lost.{% endblocktrans %}"
|
|
onclick="return confirm(this.dataset.confirm)">{% bs_icon 'repeat' %} {% trans "Power cycle" %}</button>
|
|
</form></li>
|
|
{% endif %}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|