From e324e79fcbd193d82a20d4178539582e4395214c Mon Sep 17 00:00:00 2001 From: catborise Date: Wed, 21 Oct 2026 12:49:52 +0300 Subject: [PATCH] fix(templates): a wide table scrolls in its own box on a narrow screen Twenty tables had no .table-responsive wrapper, so on a phone the user list, compute list, VM lists, network and network filter pages scrolled sideways as a whole. Each table now scrolls inside its box, as the other ten already did. The page test walks the network page too, and checks that every table on every page has the wrapper. Co-Authored-By: Claude Opus 5.5 (1M context) --- accounts/templates/account.html | 98 +-- admin/templates/admin/group_list.html | 56 +- admin/templates/admin/tombstone_list.html | 68 +- admin/templates/admin/user_list.html | 96 +-- computes/templates/computes/instances.html | 84 +-- computes/templates/computes/list.html | 78 +-- .../templates/allinstances_index_grouped.html | 172 ++--- .../allinstances_index_nongrouped.html | 110 ++-- instances/templates/create_inst_block.html | 84 +-- .../templates/instances/settings_tab.html | 586 +++++++++--------- interfaces/templates/interface.html | 42 +- networks/templates/network.html | 220 +++---- nwfilters/templates/nwfilter.html | 112 ++-- storages/templates/storage.html | 182 +++--- .../{test_unique_ids.py => test_pages.py} | 32 +- 15 files changed, 1038 insertions(+), 982 deletions(-) rename webvirtcloud/tests/{test_unique_ids.py => test_pages.py} (67%) diff --git a/accounts/templates/account.html b/accounts/templates/account.html index b7df91ed..2e52c967 100644 --- a/accounts/templates/account.html +++ b/accounts/templates/account.html @@ -38,57 +38,61 @@
- - - - - - - - - - - - - {% for inst in user_insts %} +
+
#{% trans "Instance" %}{% trans "VNC" %}{% trans "Resize" %}{% trans "Delete" %}{% trans "Action" %}
+ - - - - - - - + + + + + + - {% endfor %} - -
{{ forloop.counter }}{{ inst.instance.name }}{{ inst.is_vnc }}{{ inst.is_change }}{{ inst.is_delete }} - - {% bs_icon 'pencil' %} - - - - {% bs_icon 'trash' %} - - #{% trans "Instance" %}{% trans "VNC" %}{% trans "Resize" %}{% trans "Delete" %}{% trans "Action" %}
+ + + {% for inst in user_insts %} + + {{ forloop.counter }} + {{ inst.instance.name }} + {{ inst.is_vnc }} + {{ inst.is_change }} + {{ inst.is_delete }} + + + {% bs_icon 'pencil' %} + + + + + {% bs_icon 'trash' %} + + + + {% endfor %} + + +
- - - - - - - - - {% for publickey in publickeys %} - - - - - {% endfor %} - -
{% trans "Key name" %}{% trans "Public key" %}
{{ publickey.keyname }}{{ publickey.keypublic|truncatechars:64 }}
+
+ + + + + + + + + {% for publickey in publickeys %} + + + + + {% endfor %} + +
{% trans "Key name" %}{% trans "Public key" %}
{{ publickey.keyname }}{{ publickey.keypublic|truncatechars:64 }}
+
{% endblock content %} diff --git a/admin/templates/admin/group_list.html b/admin/templates/admin/group_list.html index 6b7c14cd..78d61186 100644 --- a/admin/templates/admin/group_list.html +++ b/admin/templates/admin/group_list.html @@ -22,33 +22,35 @@ {% else %}
- - - - - - - - - {% for group in groups %} - - - - - {% endfor %} - -
{% trans "Group Name" %}{% trans "Actions" %}
- {{ group.name }} - - -
+
+ + + + + + + + + {% for group in groups %} + + + + + {% endfor %} + +
{% trans "Group Name" %}{% trans "Actions" %}
+ {{ group.name }} + + +
+
{% endif %} diff --git a/admin/templates/admin/tombstone_list.html b/admin/templates/admin/tombstone_list.html index 3d9f788d..b182c031 100644 --- a/admin/templates/admin/tombstone_list.html +++ b/admin/templates/admin/tombstone_list.html @@ -20,39 +20,41 @@ {% else %}
- - - - - - - - - - - - - {% for tombstone in tombstones %} - - - - - - - - - {% endfor %} - -
{% trans "Name" %}{% trans "UUID" %}{% trans "Owners" %}{% trans "Removed" %}{% trans "Expires" %}{% trans "Actions" %}
- {{ tombstone.name }} - {% if tombstone.is_template %}{% trans "Template" %}{% endif %} - {{ tombstone.uuid }}{{ tombstone.owner_names|join:", " }}{{ tombstone.removed|date:"Y-m-d H:i" }}{{ tombstone.expires|date:"Y-m-d H:i" }} - -
+
+ + + + + + + + + + + + + {% for tombstone in tombstones %} + + + + + + + + + {% endfor %} + +
{% trans "Name" %}{% trans "UUID" %}{% trans "Owners" %}{% trans "Removed" %}{% trans "Expires" %}{% trans "Actions" %}
+ {{ tombstone.name }} + {% if tombstone.is_template %}{% trans "Template" %}{% endif %} + {{ tombstone.uuid }}{{ tombstone.owner_names|join:", " }}{{ tombstone.removed|date:"Y-m-d H:i" }}{{ tombstone.expires|date:"Y-m-d H:i" }} + +
+
{% endif %} diff --git a/admin/templates/admin/user_list.html b/admin/templates/admin/user_list.html index 4ddf2c42..3972d0ab 100644 --- a/admin/templates/admin/user_list.html +++ b/admin/templates/admin/user_list.html @@ -25,56 +25,58 @@ {% else %}
- - - - - - - - - - - - - - {% for user in users %} - {% has_perm user 'instances.clone_instances' as can_clone %} - - - - - - - - + + + + + + + {% endfor %} + +
{% trans "Username" %}{% trans "Status" %}{% trans "Last Login" %}{% trans "Staff" %}{% trans "Superuser" %}{% trans "Can Clone" %}{% trans "Actions" %}
- {{ user.username }} - - {% if user.is_active %} - {% trans "Active" %} - {% else %} - {% trans "Blocked" %} - {% endif %} - {{ user.last_login }}{% if user.is_staff %}{% bs_icon 'check' %}{% endif %}{% if user.is_superuser %}{% bs_icon 'check' %}{% endif %}{% if can_clone %}{% bs_icon 'check' %}{% endif %} -
- {% bs_icon 'eye-fill' %} - {% bs_icon 'pencil-fill' %} +
+ + + + + + + + + + + + + + {% for user in users %} + {% has_perm user 'instances.clone_instances' as can_clone %} + + + - - {% endfor %} - -
{% trans "Username" %}{% trans "Status" %}{% trans "Last Login" %}{% trans "Staff" %}{% trans "Superuser" %}{% trans "Can Clone" %}{% trans "Actions" %}
+ {{ user.username }} + {% if user.is_active %} -
{% csrf_token %} - -
+ {% trans "Active" %} {% else %} -
{% csrf_token %} - -
+ {% trans "Blocked" %} {% endif %} - {% bs_icon 'x-circle-fill' %} - -
+
{{ user.last_login }}{% if user.is_staff %}{% bs_icon 'check' %}{% endif %}{% if user.is_superuser %}{% bs_icon 'check' %}{% endif %}{% if can_clone %}{% bs_icon 'check' %}{% endif %} +
+ {% bs_icon 'eye-fill' %} + {% bs_icon 'pencil-fill' %} + {% if user.is_active %} +
{% csrf_token %} + +
+ {% else %} +
{% csrf_token %} + +
+ {% endif %} + {% bs_icon 'x-circle-fill' %} +
+
+
{% endif %} diff --git a/computes/templates/computes/instances.html b/computes/templates/computes/instances.html index 1b828b70..0a55991c 100644 --- a/computes/templates/computes/instances.html +++ b/computes/templates/computes/instances.html @@ -66,47 +66,49 @@ {% endif %} {% else %} - - - - - - - - - - - - - {% for instance in instances %} - - - - - - - - - {% endfor %} - -
{% trans 'Name' %}
{% trans 'Description' %}
{% trans 'User' %}{% trans 'Status' %}{% trans 'VCPU' %}{% trans 'Memory' %}{% trans 'Actions' %}
- {{ instance.name }} -
- {% if instance.info %}

{{ instance.title }}

{% endif %} -
- - {% 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 %} - - - {% include 'instance_state.html' %} - {{ instance.info.3 }}

{% if instance.info %}{% widthratio instance.info.1 1024 1 %} MiB{% endif %}

- {% include 'instance_actions.html' %} -
+
+ + + + + + + + + + + + + {% for instance in instances %} + + + + + + + + + {% endfor %} + +
{% trans 'Name' %}
{% trans 'Description' %}
{% trans 'User' %}{% trans 'Status' %}{% trans 'VCPU' %}{% trans 'Memory' %}{% trans 'Actions' %}
+ {{ instance.name }} +
+ {% if instance.info %}

{{ instance.title }}

{% endif %} +
+ + {% 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 %} + + + {% include 'instance_state.html' %} + {{ instance.info.3 }}

{% if instance.info %}{% widthratio instance.info.1 1024 1 %} MiB{% endif %}

+ {% include 'instance_actions.html' %} +
+
{% endif %} diff --git a/computes/templates/computes/list.html b/computes/templates/computes/list.html index d5850d9c..d7af461c 100644 --- a/computes/templates/computes/list.html +++ b/computes/templates/computes/list.html @@ -21,44 +21,46 @@ {% else %}
- - - - - - - - - - - {% for compute in computes %} - - - - - - - {% endfor %} - -
{% trans "Name" %}{% trans "Status" %}{% trans "Details" %}{% trans "Actions" %}
- {{ compute.name }} - - {% if compute.status is True %}{% trans "Connected" %}{% else %}{% trans "Not Connected" %} -
{{ compute.connection_error }} - {% endif %} -
- {{ compute.details|default:"" }} - -
- {% if compute.status is True %} - {% bs_icon 'eye-fill' %} - {% else %} - {% bs_icon 'eye' %} - {% endif %} - {% bs_icon 'pencil-fill' %} - {% bs_icon 'x-circle-fill' %} -
-
+
+ + + + + + + + + + + {% for compute in computes %} + + + + + + + {% endfor %} + +
{% trans "Name" %}{% trans "Status" %}{% trans "Details" %}{% trans "Actions" %}
+ {{ compute.name }} + + {% if compute.status is True %}{% trans "Connected" %}{% else %}{% trans "Not Connected" %} +
{{ compute.connection_error }} + {% endif %} +
+ {{ compute.details|default:"" }} + +
+ {% if compute.status is True %} + {% bs_icon 'eye-fill' %} + {% else %} + {% bs_icon 'eye' %} + {% endif %} + {% bs_icon 'pencil-fill' %} + {% bs_icon 'x-circle-fill' %} +
+
+
{% endif %} diff --git a/instances/templates/allinstances_index_grouped.html b/instances/templates/allinstances_index_grouped.html index ad1ea64a..95ef5472 100644 --- a/instances/templates/allinstances_index_grouped.html +++ b/instances/templates/allinstances_index_grouped.html @@ -1,97 +1,99 @@ {% load i18n %} {% load bootstrap_icons %} - - - - - - - - {% if app_settings.VM_DRBD_STATUS == 'True' %} - - {% endif %} - - - - - - {% for compute in computes %} - - {% if compute.instance_set.count > 0 %} - - - - - - {% if app_settings.VM_DRBD_STATUS == 'True' %} +
+
#{% trans "Name" %}
{% trans "Description" %}
{% trans "User"%}{% trans "Status" %}{% trans "Role/Disk" %}{% trans "VCPU" %}{% trans "Memory" %}{% trans "Actions" %} & {% trans "Mem Usage" %}
- - - {{ compute.name }} - {{ compute.instance_set.count }} - - {% if compute.status is True %} - {% trans "Connected" %} - {% else %} - {% trans "Not Connected" %} - {% endif %} -
+ + + + + + + {% if app_settings.VM_DRBD_STATUS == 'True' %} + + {% endif %} + + + + + + {% for compute in computes %} + + {% if compute.instance_set.count > 0 %} + + + - {% endif %} - {% if compute.status is True %} - - - - {% else %} - - - - {% endif %} - - {% for instance in compute.instance_set.all %} - - - - {% if app_settings.VM_DRBD_STATUS == 'True' %} - + {% endif %} - - - + + + {% else %} + + + + {% endif %} - {% endfor %} - {% endif %} - - {% empty %} - {# sortable.js needs a table body #} - {% endfor %} -
#{% trans "Name" %}
{% trans "Description" %}
{% trans "User"%}{% trans "Status" %}{% trans "Role/Disk" %}{% trans "VCPU" %}{% trans "Memory" %}{% trans "Actions" %} & {% trans "Mem Usage" %}
+ + + {{ compute.name }} + {{ compute.instance_set.count }} + {{ compute.cpu_count }}{{ compute.ram_size|filesizeformat }} -
-
{{ compute.ram_usage }}% -
-
-
{{ forloop.counter }} - {{ instance.name }} -
- {% if instance.info %}

{{ instance.title }}

{% endif %} -
- - {% 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 %} - - - {% include 'instance_state.html' %} + {% if compute.status is True %} + {% trans "Connected" %} + {% else %} + {% trans "Not Connected" %} + {% endif %} - {% if instance.drbd == "Primary/OK" or instance.drbd == "Secondary/OK" %}{% else %}{% endif %}{{ instance.drbd }} - {{ instance.info.3 }}{% if instance.info %}{% widthratio instance.info.2 1024 1 %} MB{% endif %} - {% include 'instance_actions.html' %} + {% if compute.status is True %} + {{ compute.cpu_count }}{{ compute.ram_size|filesizeformat }} +
+
{{ compute.ram_usage }}% +
+
+ {% for instance in compute.instance_set.all %} + + {{ forloop.counter }} + + {{ instance.name }} +
+ {% if instance.info %}

{{ instance.title }}

{% endif %} + + + + {% 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 %} + + + + {% include 'instance_state.html' %} + + {% if app_settings.VM_DRBD_STATUS == 'True' %} + + {% if instance.drbd == "Primary/OK" or instance.drbd == "Secondary/OK" %}{% else %}{% endif %}{{ instance.drbd }} + + {% endif %} + {{ instance.info.3 }} + {% if instance.info %}{% widthratio instance.info.2 1024 1 %} MB{% endif %} + + {% include 'instance_actions.html' %} + + + {% endfor %} + {% endif %} + + {% empty %} + {# sortable.js needs a table body #} + {% endfor %} + + {% block script %}