1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00

fix(computes): the host sections are a breadcrumb again; capacity lines wrap in their card

#241 made the host sections pills: on a desktop they took two lines,
unlike the breadcrumb the pages had. computes/host_nav.html is the
breadcrumb again, one line at 1200 px and wider, still shared by the
eleven host pages: the section's own page is its bold item with
aria-current="page", an item page (a pool, a network) links its
section in bold with aria-current="true".

The capacity lines were kept on one line, made for the Computes
table: in the overview's narrower cards a long memory line ran out of
its card. They now wrap.
This commit is contained in:
catborise 2026-10-27 14:57:50 +03:00
parent 1b99d2eac5
commit 591ec4a1f5
5 changed files with 35 additions and 28 deletions

View file

@ -1,6 +1,6 @@
{% load i18n %}
{# the memory a host has given its VMs: given, from views.shown_capacity #}
<div class="mb-1 text-nowrap">{% blocktrans with all=given.assigned.all|filesizeformat memory=given.memory|filesizeformat %}{{ all }} given of {{ memory }}{% endblocktrans %}</div>
<div class="mb-1">{% blocktrans with all=given.assigned.all|filesizeformat memory=given.memory|filesizeformat %}{{ all }} given of {{ memory }}{% endblocktrans %}</div>
<div class="cap-bar" role="img" aria-label="{% blocktrans with percent=given.memory_percent %}{{ percent }}% of the host's memory given{% endblocktrans %}"
title="{% trans "Dark: running VMs. Light: shut-off VMs, which take their memory again when they start. Line: the host's memory." %}">
<div class="cap-running {% if given.bar.over %}bg-danger{% endif %}" style="width: {{ given.bar.running|stringformat:".1f" }}%"></div>

View file

@ -1,5 +1,5 @@
{% load i18n %}
{# the vCPUs a host has given its VMs: given, what its list cell and its overview show #}
<div class="compute-ratio {% if given.ratio > 4 %}text-danger{% elif given.ratio > 2 %}text-warning-emphasis{% endif %}">{{ given.ratio|floatformat:1 }}:1</div>
<div class="small text-body-secondary text-nowrap">{% blocktrans count counter=given.vcpus.all %}{{ counter }} vCPU{% plural %}{{ counter }} vCPUs{% endblocktrans %} {% blocktrans count counter=given.cpus %}on {{ counter }} CPU{% plural %}on {{ counter }} CPUs{% endblocktrans %}</div>
<div class="small text-body-secondary">{% blocktrans count counter=given.vcpus.all %}{{ counter }} vCPU{% plural %}{{ counter }} vCPUs{% endblocktrans %} {% blocktrans count counter=given.cpus %}on {{ counter }} CPU{% plural %}on {{ counter }} CPUs{% endblocktrans %}</div>
<div class="small text-body-secondary">{% blocktrans with running=given.vcpus.running %}{{ running }} running{% endblocktrans %}</div>

View file

@ -1,28 +1,35 @@
{% load i18n %}
{% load bootstrap_icons %}
{# The host's sections. section: the one this page belongs to; detail: the page is an item of it (a pool, a network), not the section's own page #}
<nav class="mb-3" aria-label="{% trans "Host sections" %}">
<ul class="nav nav-pills flex-wrap gap-1">
<li class="nav-item">
<a class="nav-link{% if section == "overview" %} active{% endif %}" href="{% url 'overview' compute.id %}"{% if section == "overview" %} aria-current="{{ detail|yesno:"true,page" }}"{% endif %}>{% bs_icon 'laptop' %} {% trans "Overview" %}</a>
<nav aria-label="{% trans "Host sections" %}">
<ol class="breadcrumb shadow-sm">
<li class="breadcrumb-item">
{% if section == "overview" and not detail %}<span class="fw-bold" aria-current="page">{% bs_icon 'laptop' %} {% trans "Overview" %}</span>
{% else %}<a href="{% url 'overview' compute.id %}"{% if section == "overview" %} class="fw-bold" aria-current="true"{% endif %}>{% bs_icon 'laptop' %} {% trans "Overview" %}</a>{% endif %}
</li>
<li class="nav-item">
<a class="nav-link{% if section == "instances" %} active{% endif %}" href="{% url 'instances' compute.id %}"{% if section == "instances" %} aria-current="{{ detail|yesno:"true,page" }}"{% endif %}>{% bs_icon 'server' %} {% trans "Instances" %}</a>
<li class="breadcrumb-item">
{% if section == "instances" and not detail %}<span class="fw-bold" aria-current="page">{% bs_icon 'server' %} {% trans "Instances" %}</span>
{% else %}<a href="{% url 'instances' compute.id %}"{% if section == "instances" %} class="fw-bold" aria-current="true"{% endif %}>{% bs_icon 'server' %} {% trans "Instances" %}</a>{% endif %}
</li>
<li class="nav-item">
<a class="nav-link{% if section == "storages" %} active{% endif %}" href="{% url 'storages' compute.id %}"{% if section == "storages" %} aria-current="{{ detail|yesno:"true,page" }}"{% endif %}>{% bs_icon 'device-hdd' %} {% trans "Storages" %}</a>
<li class="breadcrumb-item">
{% if section == "storages" and not detail %}<span class="fw-bold" aria-current="page">{% bs_icon 'device-hdd' %} {% trans "Storages" %}</span>
{% else %}<a href="{% url 'storages' compute.id %}"{% if section == "storages" %} class="fw-bold" aria-current="true"{% endif %}>{% bs_icon 'device-hdd' %} {% trans "Storages" %}</a>{% endif %}
</li>
<li class="nav-item">
<a class="nav-link{% if section == "networks" %} active{% endif %}" href="{% url 'networks' compute.id %}"{% if section == "networks" %} aria-current="{{ detail|yesno:"true,page" }}"{% endif %}>{% bs_icon 'hdd-network' %} {% trans "Networks" %}</a>
<li class="breadcrumb-item">
{% if section == "networks" and not detail %}<span class="fw-bold" aria-current="page">{% bs_icon 'hdd-network' %} {% trans "Networks" %}</span>
{% else %}<a href="{% url 'networks' compute.id %}"{% if section == "networks" %} class="fw-bold" aria-current="true"{% endif %}>{% bs_icon 'hdd-network' %} {% trans "Networks" %}</a>{% endif %}
</li>
<li class="nav-item">
<a class="nav-link{% if section == "interfaces" %} active{% endif %}" href="{% url 'interfaces' compute.id %}"{% if section == "interfaces" %} aria-current="{{ detail|yesno:"true,page" }}"{% endif %}>{% bs_icon 'wifi' %} {% trans "Interfaces" %}</a>
<li class="breadcrumb-item">
{% if section == "interfaces" and not detail %}<span class="fw-bold" aria-current="page">{% bs_icon 'wifi' %} {% trans "Interfaces" %}</span>
{% else %}<a href="{% url 'interfaces' compute.id %}"{% if section == "interfaces" %} class="fw-bold" aria-current="true"{% endif %}>{% bs_icon 'wifi' %} {% trans "Interfaces" %}</a>{% endif %}
</li>
<li class="nav-item">
<a class="nav-link{% if section == "nwfilters" %} active{% endif %}" href="{% url 'nwfilters' compute.id %}"{% if section == "nwfilters" %} aria-current="{{ detail|yesno:"true,page" }}"{% endif %}>{% bs_icon 'filter' %} {% trans "NWFilters" %}</a>
<li class="breadcrumb-item">
{% if section == "nwfilters" and not detail %}<span class="fw-bold" aria-current="page">{% bs_icon 'filter' %} {% trans "NWFilters" %}</span>
{% else %}<a href="{% url 'nwfilters' compute.id %}"{% if section == "nwfilters" %} class="fw-bold" aria-current="true"{% endif %}>{% bs_icon 'filter' %} {% trans "NWFilters" %}</a>{% endif %}
</li>
<li class="nav-item">
<a class="nav-link{% if section == "virtsecrets" %} active{% endif %}" href="{% url 'virtsecrets' compute.id %}"{% if section == "virtsecrets" %} aria-current="{{ detail|yesno:"true,page" }}"{% endif %}>{% bs_icon 'key' %} {% trans "Secrets" %}</a>
<li class="breadcrumb-item">
{% if section == "virtsecrets" and not detail %}<span class="fw-bold" aria-current="page">{% bs_icon 'key' %} {% trans "Secrets" %}</span>
{% else %}<a href="{% url 'virtsecrets' compute.id %}"{% if section == "virtsecrets" %} class="fw-bold" aria-current="true"{% endif %}>{% bs_icon 'key' %} {% trans "Secrets" %}</a>{% endif %}
</li>
</ul>
</ol>
</nav>

View file

@ -3,4 +3,4 @@
<div class="cap-bar cap-thin my-1" role="img" aria-label="{% blocktrans with name=pool.name percent=pool.used_percent|floatformat:0 %}{{ name }} {{ percent }}% used{% endblocktrans %}">
<div class="cap-running {% if pool.used_percent > 90 %}bg-danger{% elif pool.used_percent > 75 %}bg-warning{% endif %}" style="width: {{ pool.used_percent|stringformat:".1f" }}%"></div>
</div>
<div class="small text-body-secondary text-nowrap">{% blocktrans with free=pool.free|filesizeformat size=pool.size|filesizeformat %}{{ free }} free of {{ size }}{% endblocktrans %}</div>
<div class="small text-body-secondary">{% blocktrans with free=pool.free|filesizeformat size=pool.size|filesizeformat %}{{ free }} free of {{ size }}{% endblocktrans %}</div>

View file

@ -11,15 +11,15 @@ class HostNavTestCase(TestCase):
def setUp(self):
self.compute = Compute.objects.create(name="c", hostname="192.0.2.1", login="u", password="p", type=1)
def links(self, **context):
def items(self, **context):
nav = html.fromstring(render_to_string("computes/host_nav.html", {"compute": self.compute, **context}))
return {link.text_content().strip(): (link.get("class"), link.get("aria-current")) for link in nav.iter("a")}
return {item.text_content().strip(): (item.tag, item.get("aria-current")) for item in nav.xpath("//li/*")}
def test_the_section_s_own_page_is_the_current_page(self):
links = self.links(section="storages")
self.assertEqual(len(links), 7)
self.assertEqual(links["Storages"], ("nav-link active", "page"))
self.assertEqual(links["Overview"], ("nav-link", None))
items = self.items(section="storages")
self.assertEqual(len(items), 7)
self.assertEqual(items["Storages"], ("span", "page"))
self.assertEqual(items["Overview"], ("a", None))
def test_an_item_of_a_section_marks_the_section_without_being_its_page(self):
self.assertEqual(self.links(section="networks", detail=True)["Networks"], ("nav-link active", "true"))
def test_an_item_of_a_section_links_the_section_as_where_it_is(self):
self.assertEqual(self.items(section="networks", detail=True)["Networks"], ("a", "true"))