mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
style(admin): the group form has the user form's layout and a members search
The group form put every user as a checkbox in one unsorted list, the members among them, with no way to find one: past a few dozen users a wall of names. Its name field ran the width of the page. It now has the user form's sections (Group, Permissions, Members), each with what it is for beside its fields. Members come first, then everyone else, each by username with their full name; a search box filters them by username, name or e-mail (table_filter.js). A form's search, marked data-forget, starts empty: the list pages remember theirs per page title, which here is the same for every group. Hidden users stay in the form, so saving while filtered keeps them. The button says Create group or Save changes.
This commit is contained in:
parent
6523fd0955
commit
61979be731
9 changed files with 223 additions and 124 deletions
|
|
@ -39,7 +39,7 @@ class GroupForm(forms.ModelForm):
|
|||
|
||||
users = forms.ModelMultipleChoiceField(
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
queryset=User.objects.all(),
|
||||
queryset=User.objects.order_by("username"),
|
||||
required=False,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,50 +1,89 @@
|
|||
{% extends "base.html" %}
|
||||
{% load django_bootstrap5 %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block page_heading %}{{ title }}{% endblock page_heading %}
|
||||
|
||||
{% block style %}
|
||||
<style>
|
||||
/* as the user form: what a section is about on the left, its fields on the right */
|
||||
.group-form-section { border-top: 1px solid var(--bs-border-color); padding: 1.5rem 0; }
|
||||
.group-form-section:first-of-type { border-top: 0; padding-top: .5rem; }
|
||||
.group-form-fields { max-width: 52rem; }
|
||||
</style>
|
||||
{% endblock style %}
|
||||
|
||||
{% block content %}
|
||||
{# as the user form: what the members may do first, then who they are #}
|
||||
<form id="create-update" method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form type="non_fields" %}
|
||||
{% bootstrap_field form.name %}
|
||||
|
||||
<h4 class="h5 mb-1">{% trans "What can its members do?" %}</h4>
|
||||
<p class="small text-body-secondary mb-2">{% trans "Each member has these permissions besides their own." %}</p>
|
||||
<div class="border-top mb-4">
|
||||
{% for box, help in form.permission_rows %}
|
||||
<div class="form-check form-switch border-bottom py-2 ps-5">
|
||||
<input id="{{ box.id_for_label }}" class="form-check-input" type="checkbox" role="switch" name="permissions"
|
||||
value="{{ box.data.value }}"{% if box.data.selected %} checked{% endif %}>
|
||||
<label class="form-check-label" for="{{ box.id_for_label }}">
|
||||
<span class="d-block">{{ box.data.value.instance.name }}</span>
|
||||
<span class="small text-body-secondary">{{ help }}</span>
|
||||
</label>
|
||||
<section class="group-form-section">
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-3">
|
||||
<h2 class="h6 fw-semibold mb-1">{% trans "Group" %}</h2>
|
||||
<p class="small text-body-secondary mb-0">{% trans "Users who share a set of permissions." %}</p>
|
||||
</div>
|
||||
<div class="col-lg-9 group-form-fields">
|
||||
<div class="row"><div class="col-sm-6">{% bootstrap_field form.name %}</div></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for error in form.permissions.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
|
||||
<fieldset class="mb-3">
|
||||
<legend class="fs-6 fw-semibold">{% trans "Members" %}</legend>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
{% for box in form.users %}
|
||||
<label class="border rounded px-2 py-1 text-break">
|
||||
<input id="{{ box.id_for_label }}" class="form-check-input me-1" type="checkbox" name="users" value="{{ box.data.value }}"{% if box.data.selected %} checked{% endif %}>
|
||||
{{ box.choice_label }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% for error in form.users.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
|
||||
</fieldset>
|
||||
</section>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-3">
|
||||
<section class="group-form-section">
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-3">
|
||||
<h2 class="h6 fw-semibold mb-1">{% trans "Permissions" %}</h2>
|
||||
<p class="small text-body-secondary mb-0">{% trans "Each member has these permissions besides their own." %}</p>
|
||||
</div>
|
||||
<div class="col-lg-9 group-form-fields">
|
||||
<div class="border-top">
|
||||
{% for box, help in form.permission_rows %}
|
||||
<div class="form-check form-switch border-bottom py-2 ps-5">
|
||||
<input id="{{ box.id_for_label }}" class="form-check-input" type="checkbox" role="switch" name="permissions"
|
||||
value="{{ box.data.value }}"{% if box.data.selected %} checked{% endif %}>
|
||||
<label class="form-check-label" for="{{ box.id_for_label }}">
|
||||
<span class="d-block">{{ box.data.value.instance.name }}</span>
|
||||
<span class="small text-body-secondary">{{ help }}</span>
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for error in form.permissions.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="group-form-section">
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-3">
|
||||
<h2 class="h6 fw-semibold mb-1">{% trans "Members" %}</h2>
|
||||
<p class="small text-body-secondary mb-0">{% trans "Who gets these permissions." %}</p>
|
||||
</div>
|
||||
<fieldset class="col-lg-9 group-form-fields">
|
||||
<legend class="visually-hidden">{% trans "Members" %}</legend>
|
||||
<input id="filter" class="form-control form-control-sm mb-2" style="max-width: 20rem" type="search" placeholder="{% trans "Search" %}" aria-label="{% trans "Search users" %}" data-forget>
|
||||
{# the members first, then everyone else; each by username #}
|
||||
<div class="d-flex flex-wrap gap-2 searchable">
|
||||
{% for box in form.users %}{% if box.data.selected %}{% include "admin/group_member.html" %}{% endif %}{% endfor %}
|
||||
{% for box in form.users %}{% if not box.data.selected %}{% include "admin/group_member.html" %}{% endif %}{% endfor %}
|
||||
</div>
|
||||
<p id="no-match" class="small text-body-secondary mt-2 mb-0" hidden>{% trans "No user matches the search." %}</p>
|
||||
{% for error in form.users.errors %}<div class="invalid-feedback d-block">{{ error }}</div>{% endfor %}
|
||||
</fieldset>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="group-form-section d-flex justify-content-end gap-2">
|
||||
<a class="btn btn-outline-secondary" href="{% url 'admin:group_list' %}">{% trans "Cancel" %}</a>
|
||||
<button type="submit" class="btn btn-primary">{% trans "Save" %}</button>
|
||||
<button type="submit" class="btn btn-primary">{% if group %}{% trans "Save changes" %}{% else %}{% trans "Create group" %}{% endif %}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{% static 'js/table_filter.js' %}"></script>
|
||||
{% endblock script %}
|
||||
|
|
|
|||
7
admin/templates/admin/group_member.html
Normal file
7
admin/templates/admin/group_member.html
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{# one user of the group form's Members: box is a checkbox of GroupForm.users #}
|
||||
{% with user=box.data.value.instance %}
|
||||
<label class="border rounded px-2 py-1 text-break" data-search="{{ user.username }} {{ user.get_full_name }} {{ user.email }}">
|
||||
<input id="{{ box.id_for_label }}" class="form-check-input me-1" type="checkbox" name="users" value="{{ box.data.value }}"{% if box.data.selected %} checked{% endif %}>
|
||||
{{ user.username }}{% if user.get_full_name %} <span class="small text-body-secondary">{{ user.get_full_name }}</span>{% endif %}
|
||||
</label>
|
||||
{% endwith %}
|
||||
|
|
@ -53,6 +53,23 @@ class AdminTestCase(TestCase):
|
|||
with self.assertRaises(ObjectDoesNotExist):
|
||||
Group.objects.get(id=group_id)
|
||||
|
||||
def test_group_form_lists_its_members_first(self):
|
||||
for name in ("zed", "bob", "amy"):
|
||||
User.objects.create_user(name)
|
||||
User.objects.filter(username="amy").update(first_name="Amy", last_name="Adams")
|
||||
group = Group.objects.create(name="Ops")
|
||||
group.user_set.add(User.objects.get(username="zed"))
|
||||
|
||||
page = html.fromstring(self.client.get(reverse("admin:group_update", args=[group.id])).content)
|
||||
boxes = page.xpath("//div[contains(@class, 'searchable')]/label")
|
||||
names = [box.text_content().split()[0] for box in boxes]
|
||||
self.assertEqual(names, ["zed", "admin", "amy", "bob"])
|
||||
self.assertIn("Amy Adams", boxes[2].get("data-search"))
|
||||
self.assertEqual(page.xpath("//input[@id='filter']/@data-forget"), [""])
|
||||
self.assertEqual(page.xpath("//form[@id='create-update']//button[@type='submit']/text()"), ["Save changes"])
|
||||
page = html.fromstring(self.client.get(reverse("admin:group_create")).content)
|
||||
self.assertEqual(page.xpath("//form[@id='create-update']//button[@type='submit']/text()"), ["Create group"])
|
||||
|
||||
def test_user_list(self):
|
||||
response = self.client.get(reverse("admin:user_list"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -11,7 +11,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-11-04 19:19+0000\n"
|
||||
"POT-Creation-Date: 2026-11-04 19:38+0000\n"
|
||||
"PO-Revision-Date: 2020-11-04 12:00+0000\n"
|
||||
"Last-Translator: catborise <muhammetalisag@gmail.com>, 2020\n"
|
||||
"Language-Team: Turkish (https://www.transifex.com/catborise/teams/110663/tr/)\n"
|
||||
|
|
@ -263,7 +263,7 @@ msgstr "Parola Değiştir"
|
|||
|
||||
#: accounts/templates/accounts/change_password_form.html:25
|
||||
#: accounts/templates/accounts/email_otp_form.html:25
|
||||
#: admin/templates/admin/group_form.html:46
|
||||
#: admin/templates/admin/group_form.html:81
|
||||
#: admin/templates/admin/user_form.html:169
|
||||
#: computes/templates/computes/form.html:45
|
||||
#: console/templates/console-vnc.html:86
|
||||
|
|
@ -670,7 +670,7 @@ msgstr "Listelerde tüm sanal makineleri ve sunucuları salt okunur görme"
|
|||
msgid "User"
|
||||
msgstr "Kullanıcı"
|
||||
|
||||
#: admin/forms.py:80
|
||||
#: admin/forms.py:80 admin/templates/admin/group_form.html:39
|
||||
msgid "Permissions"
|
||||
msgstr "İzinler"
|
||||
|
||||
|
|
@ -720,55 +720,42 @@ msgstr "Disk"
|
|||
msgid "No limit"
|
||||
msgstr "Sınır yok"
|
||||
|
||||
#: admin/forms.py:216
|
||||
#: admin/forms.py:218
|
||||
msgid "Enter a limit or choose No limit."
|
||||
msgstr "Bir sınır girin ya da Sınır yok'u seçin."
|
||||
|
||||
#: admin/forms.py:228
|
||||
#: admin/forms.py:230
|
||||
msgid "The user must change it at their next login"
|
||||
msgstr "Kullanıcı bir sonraki girişinde onu değiştirmek zorundadır"
|
||||
|
||||
#: admin/forms.py:238
|
||||
#: admin/forms.py:240
|
||||
msgid "A user without a password cannot be made to change it"
|
||||
msgstr "Parolası olmayan bir kullanıcıya parola değiştirme zorunluluğu konamaz"
|
||||
|
||||
#: admin/templates/admin/group_form.html:16
|
||||
msgid "What can its members do?"
|
||||
msgstr "Üyeleri neler yapabilir?"
|
||||
#: admin/templates/admin/group_form.html:27
|
||||
msgid "Group"
|
||||
msgstr "Grup"
|
||||
|
||||
#: admin/templates/admin/group_form.html:17
|
||||
#: admin/templates/admin/group_form.html:28
|
||||
msgid "Users who share a set of permissions."
|
||||
msgstr "Aynı izinleri paylaşan kullanıcılar."
|
||||
|
||||
#: admin/templates/admin/group_form.html:40
|
||||
msgid "Each member has these permissions besides their own."
|
||||
msgstr "Her üye kendi izinlerine ek olarak bu izinlere sahiptir."
|
||||
|
||||
#: admin/templates/admin/group_form.html:33
|
||||
#: admin/templates/admin/group_form.html:63
|
||||
#: admin/templates/admin/group_form.html:67
|
||||
#: interfaces/templates/interface.html:113
|
||||
#: interfaces/templates/interfaces.html:52
|
||||
msgid "Members"
|
||||
msgstr "Üyeler"
|
||||
|
||||
#: admin/templates/admin/group_form.html:47
|
||||
#: computes/templates/computes/form.html:46
|
||||
#: instances/templates/instances/edit_instance_volume.html:112
|
||||
#: instances/templates/instances/nic_qos_form.html:23
|
||||
#: instances/templates/instances/settings_tab.html:412
|
||||
#: instances/templates/instances/settings_tab.html:653
|
||||
#: instances/templates/instances/settings_tab.html:907
|
||||
#: networks/templates/add_network_qos.html:36
|
||||
#: networks/templates/network.html:336 networks/templates/network.html:376
|
||||
#: networks/templates/network.html:403 networks/templates/network.html:442
|
||||
#: nwfilters/templates/nwfilter.html:153 templates/common/form.html:23
|
||||
msgid "Save"
|
||||
msgstr "Kaydet"
|
||||
|
||||
#: admin/templates/admin/group_list.html:12
|
||||
msgid "New group"
|
||||
msgstr "Yeni grup"
|
||||
|
||||
#: admin/templates/admin/group_list.html:19
|
||||
#: admin/templates/admin/user_form.html:141
|
||||
msgid "There are no groups yet."
|
||||
msgstr "Henüz grup yok."
|
||||
#: admin/templates/admin/group_form.html:64
|
||||
msgid "Who gets these permissions."
|
||||
msgstr "Bu izinleri kimlerin alacağı."
|
||||
|
||||
#: admin/templates/admin/group_form.html:68
|
||||
#: admin/templates/admin/group_list.html:25 admin/templates/admin/logs.html:20
|
||||
#: admin/templates/admin/logs.html:26
|
||||
#: admin/templates/admin/tombstone_list.html:20
|
||||
|
|
@ -779,6 +766,34 @@ msgstr "Henüz grup yok."
|
|||
msgid "Search"
|
||||
msgstr "Ara"
|
||||
|
||||
#: admin/templates/admin/group_form.html:68
|
||||
#: admin/templates/admin/user_list.html:20
|
||||
msgid "Search users"
|
||||
msgstr "Kullanıcı ara"
|
||||
|
||||
#: admin/templates/admin/group_form.html:74
|
||||
#: admin/templates/admin/user_list.html:86
|
||||
msgid "No user matches the search."
|
||||
msgstr "Aramayla eşleşen kullanıcı yok."
|
||||
|
||||
#: admin/templates/admin/group_form.html:82
|
||||
#: admin/templates/admin/user_form.html:170
|
||||
msgid "Save changes"
|
||||
msgstr "Değişiklikleri kaydet"
|
||||
|
||||
#: admin/templates/admin/group_form.html:82
|
||||
msgid "Create group"
|
||||
msgstr "Grup oluştur"
|
||||
|
||||
#: admin/templates/admin/group_list.html:12
|
||||
msgid "New group"
|
||||
msgstr "Yeni grup"
|
||||
|
||||
#: admin/templates/admin/group_list.html:19
|
||||
#: admin/templates/admin/user_form.html:141
|
||||
msgid "There are no groups yet."
|
||||
msgstr "Henüz grup yok."
|
||||
|
||||
#: admin/templates/admin/group_list.html:25
|
||||
msgid "Search groups"
|
||||
msgstr "Grup ara"
|
||||
|
|
@ -1010,10 +1025,6 @@ msgstr ""
|
|||
"Kapalı olması burada hiçbir şey vermez; bir grubun verdiği hiçbir şeyi de "
|
||||
"geri almaz."
|
||||
|
||||
#: admin/templates/admin/user_form.html:170
|
||||
msgid "Save changes"
|
||||
msgstr "Değişiklikleri kaydet"
|
||||
|
||||
#: admin/templates/admin/user_form.html:170
|
||||
msgid "Create user"
|
||||
msgstr "Kullanıcı oluştur"
|
||||
|
|
@ -1027,10 +1038,6 @@ msgstr "Yeni kullanıcı"
|
|||
msgid "Users"
|
||||
msgstr "Kullanıcılar"
|
||||
|
||||
#: admin/templates/admin/user_list.html:20
|
||||
msgid "Search users"
|
||||
msgstr "Kullanıcı ara"
|
||||
|
||||
#: admin/templates/admin/user_list.html:24
|
||||
#: admin/templates/admin/user_list.html:37 instances/states.py:11
|
||||
#: instances/templates/instances/power_tab.html:19
|
||||
|
|
@ -1068,10 +1075,6 @@ msgstr "Engelle"
|
|||
msgid "Unblock"
|
||||
msgstr "Engeli Kaldır"
|
||||
|
||||
#: admin/templates/admin/user_list.html:86
|
||||
msgid "No user matches the search."
|
||||
msgstr "Aramayla eşleşen kullanıcı yok."
|
||||
|
||||
#: admin/views.py:57
|
||||
msgid "Create Group"
|
||||
msgstr "Grup Oluştur"
|
||||
|
|
@ -1983,6 +1986,19 @@ msgstr "kayıtlı"
|
|||
msgid "none"
|
||||
msgstr "hiçbiri"
|
||||
|
||||
#: computes/templates/computes/form.html:46
|
||||
#: instances/templates/instances/edit_instance_volume.html:112
|
||||
#: instances/templates/instances/nic_qos_form.html:23
|
||||
#: instances/templates/instances/settings_tab.html:412
|
||||
#: instances/templates/instances/settings_tab.html:653
|
||||
#: instances/templates/instances/settings_tab.html:907
|
||||
#: networks/templates/add_network_qos.html:36
|
||||
#: networks/templates/network.html:336 networks/templates/network.html:376
|
||||
#: networks/templates/network.html:403 networks/templates/network.html:442
|
||||
#: nwfilters/templates/nwfilter.html:153 templates/common/form.html:23
|
||||
msgid "Save"
|
||||
msgstr "Kaydet"
|
||||
|
||||
#: computes/templates/computes/host_nav.html:4
|
||||
msgid "Host sections"
|
||||
msgstr "Sunucu bölümleri"
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-11-04 19:19+0000\n"
|
||||
"POT-Creation-Date: 2026-11-04 19:38+0000\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -260,7 +260,7 @@ msgstr "修改密码"
|
|||
|
||||
#: accounts/templates/accounts/change_password_form.html:25
|
||||
#: accounts/templates/accounts/email_otp_form.html:25
|
||||
#: admin/templates/admin/group_form.html:46
|
||||
#: admin/templates/admin/group_form.html:81
|
||||
#: admin/templates/admin/user_form.html:169
|
||||
#: computes/templates/computes/form.html:45
|
||||
#: console/templates/console-vnc.html:86
|
||||
|
|
@ -653,7 +653,7 @@ msgstr "在列表中查看所有虚拟机和主机(只读)"
|
|||
msgid "User"
|
||||
msgstr "用户"
|
||||
|
||||
#: admin/forms.py:80
|
||||
#: admin/forms.py:80 admin/templates/admin/group_form.html:39
|
||||
msgid "Permissions"
|
||||
msgstr "权限"
|
||||
|
||||
|
|
@ -702,55 +702,42 @@ msgstr "磁盘"
|
|||
msgid "No limit"
|
||||
msgstr "不限"
|
||||
|
||||
#: admin/forms.py:216
|
||||
#: admin/forms.py:218
|
||||
msgid "Enter a limit or choose No limit."
|
||||
msgstr "请输入限制值,或选择“不限”。"
|
||||
|
||||
#: admin/forms.py:228
|
||||
#: admin/forms.py:230
|
||||
msgid "The user must change it at their next login"
|
||||
msgstr "用户必须在下次登录时修改密码"
|
||||
|
||||
#: admin/forms.py:238
|
||||
#: admin/forms.py:240
|
||||
msgid "A user without a password cannot be made to change it"
|
||||
msgstr "没有密码的用户无法被要求修改密码"
|
||||
|
||||
#: admin/templates/admin/group_form.html:16
|
||||
msgid "What can its members do?"
|
||||
msgstr "其成员可以做什么?"
|
||||
#: admin/templates/admin/group_form.html:27
|
||||
msgid "Group"
|
||||
msgstr "用户组"
|
||||
|
||||
#: admin/templates/admin/group_form.html:17
|
||||
#: admin/templates/admin/group_form.html:28
|
||||
msgid "Users who share a set of permissions."
|
||||
msgstr "共享同一组权限的用户。"
|
||||
|
||||
#: admin/templates/admin/group_form.html:40
|
||||
msgid "Each member has these permissions besides their own."
|
||||
msgstr "每个成员除自身权限外还拥有这些权限。"
|
||||
|
||||
#: admin/templates/admin/group_form.html:33
|
||||
#: admin/templates/admin/group_form.html:63
|
||||
#: admin/templates/admin/group_form.html:67
|
||||
#: interfaces/templates/interface.html:113
|
||||
#: interfaces/templates/interfaces.html:52
|
||||
msgid "Members"
|
||||
msgstr "成员"
|
||||
|
||||
#: admin/templates/admin/group_form.html:47
|
||||
#: computes/templates/computes/form.html:46
|
||||
#: instances/templates/instances/edit_instance_volume.html:112
|
||||
#: instances/templates/instances/nic_qos_form.html:23
|
||||
#: instances/templates/instances/settings_tab.html:412
|
||||
#: instances/templates/instances/settings_tab.html:653
|
||||
#: instances/templates/instances/settings_tab.html:907
|
||||
#: networks/templates/add_network_qos.html:36
|
||||
#: networks/templates/network.html:336 networks/templates/network.html:376
|
||||
#: networks/templates/network.html:403 networks/templates/network.html:442
|
||||
#: nwfilters/templates/nwfilter.html:153 templates/common/form.html:23
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
#: admin/templates/admin/group_list.html:12
|
||||
msgid "New group"
|
||||
msgstr "新建用户组"
|
||||
|
||||
#: admin/templates/admin/group_list.html:19
|
||||
#: admin/templates/admin/user_form.html:141
|
||||
msgid "There are no groups yet."
|
||||
msgstr "还没有用户组。"
|
||||
#: admin/templates/admin/group_form.html:64
|
||||
msgid "Who gets these permissions."
|
||||
msgstr "获得这些权限的用户。"
|
||||
|
||||
#: admin/templates/admin/group_form.html:68
|
||||
#: admin/templates/admin/group_list.html:25 admin/templates/admin/logs.html:20
|
||||
#: admin/templates/admin/logs.html:26
|
||||
#: admin/templates/admin/tombstone_list.html:20
|
||||
|
|
@ -761,6 +748,34 @@ msgstr "还没有用户组。"
|
|||
msgid "Search"
|
||||
msgstr "搜索"
|
||||
|
||||
#: admin/templates/admin/group_form.html:68
|
||||
#: admin/templates/admin/user_list.html:20
|
||||
msgid "Search users"
|
||||
msgstr "搜索用户"
|
||||
|
||||
#: admin/templates/admin/group_form.html:74
|
||||
#: admin/templates/admin/user_list.html:86
|
||||
msgid "No user matches the search."
|
||||
msgstr "没有与搜索匹配的用户。"
|
||||
|
||||
#: admin/templates/admin/group_form.html:82
|
||||
#: admin/templates/admin/user_form.html:170
|
||||
msgid "Save changes"
|
||||
msgstr "保存更改"
|
||||
|
||||
#: admin/templates/admin/group_form.html:82
|
||||
msgid "Create group"
|
||||
msgstr "创建用户组"
|
||||
|
||||
#: admin/templates/admin/group_list.html:12
|
||||
msgid "New group"
|
||||
msgstr "新建用户组"
|
||||
|
||||
#: admin/templates/admin/group_list.html:19
|
||||
#: admin/templates/admin/user_form.html:141
|
||||
msgid "There are no groups yet."
|
||||
msgstr "还没有用户组。"
|
||||
|
||||
#: admin/templates/admin/group_list.html:25
|
||||
msgid "Search groups"
|
||||
msgstr "搜索用户组"
|
||||
|
|
@ -984,10 +999,6 @@ msgstr "自身权限"
|
|||
msgid "Off grants nothing here; it takes away nothing a group grants."
|
||||
msgstr "关闭不会在此授予任何权限,也不会撤销用户组授予的权限。"
|
||||
|
||||
#: admin/templates/admin/user_form.html:170
|
||||
msgid "Save changes"
|
||||
msgstr "保存更改"
|
||||
|
||||
#: admin/templates/admin/user_form.html:170
|
||||
msgid "Create user"
|
||||
msgstr "创建用户"
|
||||
|
|
@ -1001,10 +1012,6 @@ msgstr "新建用户"
|
|||
msgid "Users"
|
||||
msgstr "用户"
|
||||
|
||||
#: admin/templates/admin/user_list.html:20
|
||||
msgid "Search users"
|
||||
msgstr "搜索用户"
|
||||
|
||||
#: admin/templates/admin/user_list.html:24
|
||||
#: admin/templates/admin/user_list.html:37 instances/states.py:11
|
||||
#: instances/templates/instances/power_tab.html:19
|
||||
|
|
@ -1041,10 +1048,6 @@ msgstr "禁用"
|
|||
msgid "Unblock"
|
||||
msgstr "解除禁用"
|
||||
|
||||
#: admin/templates/admin/user_list.html:86
|
||||
msgid "No user matches the search."
|
||||
msgstr "没有与搜索匹配的用户。"
|
||||
|
||||
#: admin/views.py:57
|
||||
msgid "Create Group"
|
||||
msgstr "创建用户组"
|
||||
|
|
@ -1914,6 +1917,19 @@ msgstr "已保存"
|
|||
msgid "none"
|
||||
msgstr "无"
|
||||
|
||||
#: computes/templates/computes/form.html:46
|
||||
#: instances/templates/instances/edit_instance_volume.html:112
|
||||
#: instances/templates/instances/nic_qos_form.html:23
|
||||
#: instances/templates/instances/settings_tab.html:412
|
||||
#: instances/templates/instances/settings_tab.html:653
|
||||
#: instances/templates/instances/settings_tab.html:907
|
||||
#: networks/templates/add_network_qos.html:36
|
||||
#: networks/templates/network.html:336 networks/templates/network.html:376
|
||||
#: networks/templates/network.html:403 networks/templates/network.html:442
|
||||
#: nwfilters/templates/nwfilter.html:153 templates/common/form.html:23
|
||||
msgid "Save"
|
||||
msgstr "保存"
|
||||
|
||||
#: computes/templates/computes/host_nav.html:4
|
||||
msgid "Host sections"
|
||||
msgstr "主机栏目"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
// be the chosen state too. In a grouped list a search for a group's host
|
||||
// shows all of its rows, and its header row (data-group-header) shows while
|
||||
// any of its rows does. A page's #no-match shows while no row does. The
|
||||
// search is remembered for a day, per page.
|
||||
// search is remembered for a day, per page, unless its box has data-forget.
|
||||
//
|
||||
// The instance list's state pills (#state-pills) set the state; each one's
|
||||
// [data-count-state] counts the VMs of its state the search finds (its
|
||||
|
|
@ -68,9 +68,13 @@ if (typeof module !== "undefined") {
|
|||
} else {
|
||||
var search = document.getElementById("filter");
|
||||
var states = document.getElementById("state-filter");
|
||||
search.value = Cookies.get(document.title + "_filter") || "";
|
||||
// a form's search ([data-forget], the group form's members) starts empty
|
||||
var remember = !search.hasAttribute("data-forget");
|
||||
search.value = remember && Cookies.get(document.title + "_filter") || "";
|
||||
search.addEventListener("input", function () {
|
||||
Cookies.set(document.title + "_filter", search.value, {expires: 1});
|
||||
if (remember) {
|
||||
Cookies.set(document.title + "_filter", search.value, {expires: 1});
|
||||
}
|
||||
filterTable(document);
|
||||
});
|
||||
if (states) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue