You've already forked snikket-web-portal
Create "Edit user" form
This aggregates the user actions behind a single "edit" button on the list view, making it less crammed. It also offers the functionality of actually editing the user, mind. Also in preparation for #42. Requires https://hg.prosody.im/prosody-modules/rev/5bc706c2db8f.
This commit is contained in:
@@ -35,7 +35,6 @@ async def index() -> str:
|
|||||||
|
|
||||||
|
|
||||||
class PasswordResetLinkPost(BaseForm):
|
class PasswordResetLinkPost(BaseForm):
|
||||||
action_create = wtforms.StringField()
|
|
||||||
action_revoke = wtforms.StringField()
|
action_revoke = wtforms.StringField()
|
||||||
|
|
||||||
|
|
||||||
@@ -57,6 +56,68 @@ async def users() -> str:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EditUserForm(BaseForm):
|
||||||
|
localpart = wtforms.StringField(
|
||||||
|
_l("Login name"),
|
||||||
|
)
|
||||||
|
|
||||||
|
display_name = wtforms.StringField(
|
||||||
|
_l("Display name"),
|
||||||
|
)
|
||||||
|
|
||||||
|
action_save = wtforms.SubmitField(
|
||||||
|
_l("Update user"),
|
||||||
|
)
|
||||||
|
|
||||||
|
action_create_reset = wtforms.SubmitField(
|
||||||
|
_l("Create password reset link"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/user/<localpart>/", methods=["GET", "POST"])
|
||||||
|
@client.require_admin_session()
|
||||||
|
async def edit_user(localpart: str) -> typing.Union[quart.Response, str]:
|
||||||
|
target_user_info = await client.get_user_by_localpart(localpart)
|
||||||
|
|
||||||
|
form = EditUserForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
if form.action_create_reset.data:
|
||||||
|
target_user_info = await client.get_user_by_localpart(localpart)
|
||||||
|
reset_link = await client.create_password_reset_invite(
|
||||||
|
localpart=localpart,
|
||||||
|
ttl=86400,
|
||||||
|
)
|
||||||
|
await flash(
|
||||||
|
_("Password reset link created"),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
|
return redirect(url_for(
|
||||||
|
".user_password_reset_link",
|
||||||
|
id_=reset_link.id_,
|
||||||
|
))
|
||||||
|
|
||||||
|
await client.update_user(
|
||||||
|
localpart,
|
||||||
|
display_name=form.display_name.data,
|
||||||
|
)
|
||||||
|
|
||||||
|
await flash(
|
||||||
|
_("User information updated."),
|
||||||
|
"success",
|
||||||
|
)
|
||||||
|
return redirect(url_for(".edit_user", localpart=localpart))
|
||||||
|
|
||||||
|
elif request.method == "GET":
|
||||||
|
form.localpart.data = target_user_info.localpart
|
||||||
|
form.display_name.data = target_user_info.display_name
|
||||||
|
|
||||||
|
return await render_template(
|
||||||
|
"admin_edit_user.html",
|
||||||
|
target_user=target_user_info,
|
||||||
|
form=form,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DeleteUserForm(BaseForm):
|
class DeleteUserForm(BaseForm):
|
||||||
action_delete = wtforms.SubmitField(
|
action_delete = wtforms.SubmitField(
|
||||||
_l("Delete user permanently")
|
_l("Delete user permanently")
|
||||||
@@ -100,36 +161,38 @@ async def debug_user(localpart: str) -> typing.Union[str, quart.Response]:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/users/password-reset/-", methods=["POST"])
|
@bp.route("/users/password-reset/<id_>", methods=["GET", "POST"])
|
||||||
@client.require_admin_session()
|
@client.require_admin_session()
|
||||||
async def create_password_reset_link() -> typing.Union[str, quart.Response]:
|
async def user_password_reset_link(
|
||||||
form = PasswordResetLinkPost()
|
id_: str,
|
||||||
if not form.validate_on_submit():
|
) -> typing.Union[str, quart.Response]:
|
||||||
abort(400)
|
invite_info = await client.get_invite_by_id(
|
||||||
|
id_,
|
||||||
if form.action_create.data:
|
|
||||||
localpart = form.action_create.data
|
|
||||||
target_user_info = await client.get_user_by_localpart(localpart)
|
|
||||||
reset_link = await client.create_password_reset_invite(
|
|
||||||
localpart=localpart,
|
|
||||||
ttl=86400,
|
|
||||||
)
|
)
|
||||||
|
if invite_info.jid is None:
|
||||||
await flash(
|
await flash(
|
||||||
_("Password reset link created"),
|
_("Password reset link not found"),
|
||||||
"success",
|
"alert",
|
||||||
)
|
)
|
||||||
elif form.action_revoke.data:
|
return redirect(url_for(".users"))
|
||||||
await client.delete_invite(form.action_revoke.data)
|
|
||||||
|
localpart = prosodyclient.split_jid(invite_info.jid)[0]
|
||||||
|
|
||||||
|
form = PasswordResetLinkPost()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
if form.action_revoke.data:
|
||||||
|
await client.delete_invite(id_)
|
||||||
await flash(
|
await flash(
|
||||||
_("Password reset link deleted"),
|
_("Password reset link deleted"),
|
||||||
"success",
|
"success",
|
||||||
)
|
)
|
||||||
return redirect(url_for(".users"))
|
return redirect(url_for(".edit_user", localpart=localpart))
|
||||||
|
abort(400)
|
||||||
|
|
||||||
return await render_template(
|
return await render_template(
|
||||||
"admin_reset_user_password.html",
|
"admin_reset_user_password.html",
|
||||||
target_user=target_user_info,
|
localpart=localpart,
|
||||||
reset_link=reset_link,
|
reset_link=invite_info,
|
||||||
form=form,
|
form=form,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -858,6 +858,26 @@ class ProsodyClient:
|
|||||||
self._raise_error_from_response(resp)
|
self._raise_error_from_response(resp)
|
||||||
return AdminUserInfo.from_api_response(await resp.json())
|
return AdminUserInfo.from_api_response(await resp.json())
|
||||||
|
|
||||||
|
@autosession
|
||||||
|
async def update_user(
|
||||||
|
self,
|
||||||
|
localpart: str,
|
||||||
|
*,
|
||||||
|
display_name: typing.Optional[str],
|
||||||
|
session: aiohttp.ClientSession,
|
||||||
|
) -> None:
|
||||||
|
payload = {
|
||||||
|
"username": localpart,
|
||||||
|
}
|
||||||
|
if display_name is not None:
|
||||||
|
payload["display_name"] = display_name
|
||||||
|
|
||||||
|
async with session.put(
|
||||||
|
self._admin_v1_endpoint("/users/{}".format(localpart)),
|
||||||
|
json=payload,
|
||||||
|
) as resp:
|
||||||
|
self._raise_error_from_response(resp)
|
||||||
|
|
||||||
@autosession
|
@autosession
|
||||||
async def get_user_debug_info(
|
async def get_user_debug_info(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<p>{% trans %}The user and their data will be deleted irrevocably, permanently and immediately upon pushing the below button. <strong>There is no way back!</strong>{% endtrans %}</p>
|
<p>{% trans %}The user and their data will be deleted irrevocably, permanently and immediately upon pushing the below button. <strong>There is no way back!</strong>{% endtrans %}</p>
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
<div class="f-bbox">
|
<div class="f-bbox">
|
||||||
{%- call standard_button("back", url_for(".index"), class="tertiary") %}{% trans %}Back{% endtrans %}{% endcall -%}
|
{%- call standard_button("back", url_for(".edit_user", localpart=target_user.localpart), class="tertiary") %}{% trans %}Back{% endtrans %}{% endcall -%}
|
||||||
{%- call form_button("delete", form.action_delete, class="primary danger") %}{% endcall -%}
|
{%- call form_button("delete", form.action_delete, class="primary danger") %}{% endcall -%}
|
||||||
</div>
|
</div>
|
||||||
</form></div>
|
</form></div>
|
||||||
|
|||||||
47
snikket_web/templates/admin_edit_user.html
Normal file
47
snikket_web/templates/admin_edit_user.html
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{% extends "admin_app.html" %}
|
||||||
|
{% from "library.j2" import box, form_button, standard_button %}
|
||||||
|
{% block content %}
|
||||||
|
<h1>{% trans user_name=target_user.localpart %}Edit user {{ user_name }}{% endtrans %}</h1>
|
||||||
|
<div class="form layout-expanded"><form method="POST">
|
||||||
|
{{ form.csrf_token }}
|
||||||
|
<h2 class="form-title">{% trans %}Edit user{% endtrans %}</h2>
|
||||||
|
<div class="f-ebox">
|
||||||
|
{{ form.localpart.label }}
|
||||||
|
{{ form.localpart(readonly="readonly") }}
|
||||||
|
<p class="form-desc weak">{% trans %}The login name cannot be changed.{% endtrans %}</p>
|
||||||
|
</div>
|
||||||
|
<div class="f-ebox">
|
||||||
|
{{ form.display_name.label }}
|
||||||
|
{{ form.display_name }}
|
||||||
|
</div>
|
||||||
|
<div class="f-bbox">
|
||||||
|
{%- call standard_button("back", url_for(".users"), class="tertiary") -%}
|
||||||
|
{%- trans -%}Return to user list{%- endtrans -%}
|
||||||
|
{%- endcall -%}
|
||||||
|
{%- call standard_button("delete", url_for(".delete_user", localpart=target_user.localpart), class="secondary") -%}
|
||||||
|
{%- trans -%}Delete user{%- endtrans -%}
|
||||||
|
{%- endcall -%}
|
||||||
|
{%- call form_button("done", form.action_save, class="primary") %}{% endcall -%}
|
||||||
|
</div>
|
||||||
|
</form></div>
|
||||||
|
<h2>{% trans %}Further actions{% endtrans %}</h2>
|
||||||
|
<div class="form layout-expanded"><form method="POST">
|
||||||
|
<h2 class="form-title">{% trans %}Reset password{% endtrans %}</h2>
|
||||||
|
{{ form.csrf_token }}
|
||||||
|
<p class="form-desc">
|
||||||
|
{% trans %}If the user has lost their password, you can use the button below to create a special link which allows to change the password of the account, once.{% endtrans %}
|
||||||
|
</p>
|
||||||
|
<div class="f-bbox">
|
||||||
|
{%- call form_button("passwd", form.action_create_reset, class="primary") -%}{%- endcall -%}
|
||||||
|
</div>
|
||||||
|
<h2 class="form-title">{% trans %}Debug information{% endtrans %}</h2>
|
||||||
|
<p class="form-desc">
|
||||||
|
{% trans %}In some cases, extended information about the user account and the connected devices is necessary to troubleshoot issues. The button below reveals this (sensitive) information.{% endtrans %}
|
||||||
|
</p>
|
||||||
|
<div class="f-bbox">
|
||||||
|
{%- call standard_button("bug_report", url_for(".debug_user", localpart=target_user.localpart), class="primary") -%}
|
||||||
|
{%- trans -%}Show debug information{%- endtrans -%}
|
||||||
|
{%- endcall -%}
|
||||||
|
</div>
|
||||||
|
</form></div>
|
||||||
|
{% endblock %}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<form method="POST">
|
<form method="POST">
|
||||||
{{- form.csrf_token -}}
|
{{- form.csrf_token -}}
|
||||||
<div class="form layout-expanded">
|
<div class="form layout-expanded">
|
||||||
<h2 class="form-title">{% trans user_name=target_user.localpart %}Password reset link for {{ user_name }}{% endtrans %}</h2>
|
<h2 class="form-title">{% trans user_name=localpart %}Password reset link for {{ user_name }}{% endtrans %}</h2>
|
||||||
<p class="form-desc">{% trans %}The following link will allow the user to reset their password on their device, once.{% endtrans %}</p>
|
<p class="form-desc">{% trans %}The following link will allow the user to reset their password on their device, once.{% endtrans %}</p>
|
||||||
<dd>
|
<dd>
|
||||||
<dt>{% trans %}Valid until{% endtrans %}</dt>
|
<dt>{% trans %}Valid until{% endtrans %}</dt>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
{%- call custom_form_button("remove_link", form.action_revoke.name, reset_link.id_, class="secondary danger") -%}
|
{%- call custom_form_button("remove_link", form.action_revoke.name, reset_link.id_, class="secondary danger") -%}
|
||||||
{% trans %}Destroy link{% endtrans %}
|
{% trans %}Destroy link{% endtrans %}
|
||||||
{%- endcall -%}
|
{%- endcall -%}
|
||||||
{%- call standard_button("back", url_for(".users"), class="primary") -%}
|
{%- call standard_button("back", url_for(".edit_user", localpart=localpart), class="primary") -%}
|
||||||
{% trans %}Back{% endtrans %}
|
{% trans %}Back{% endtrans %}
|
||||||
{%- endcall -%}
|
{%- endcall -%}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
{% from "library.j2" import action_button, value_or_hint, custom_form_button %}
|
{% from "library.j2" import action_button, value_or_hint, custom_form_button %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% trans %}Manage users{% endtrans %}</h1>
|
<h1>{% trans %}Manage users{% endtrans %}</h1>
|
||||||
<form method="POST" action="{{ url_for(".create_password_reset_link") }}">
|
|
||||||
{{- reset_form.csrf_token -}}
|
|
||||||
<div class="elevated el-2"><table>
|
<div class="elevated el-2"><table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -18,14 +16,8 @@
|
|||||||
<td>{{ user.localpart }}</td>
|
<td>{{ user.localpart }}</td>
|
||||||
<td>{% call value_or_hint(user.display_name) %}{% endcall %}</td>
|
<td>{% call value_or_hint(user.display_name) %}{% endcall %}</td>
|
||||||
<td class="nowrap">
|
<td class="nowrap">
|
||||||
{%- call action_button("delete", url_for(".delete_user", localpart=user.localpart), class="secondary") -%}
|
{%- call action_button("edit", url_for(".edit_user", localpart=user.localpart), class="primary") -%}
|
||||||
{% trans user_name=user.localpart %}Delete user {{ user_name }}{% endtrans %}
|
{% trans user_name=user.localpart %}Edit user {{ user_name }}{% endtrans %}
|
||||||
{%- endcall -%}
|
|
||||||
{%- call action_button("bug_report", url_for(".debug_user", localpart=user.localpart), class="secondary") -%}
|
|
||||||
{% trans user_name=user.localpart %}Show debug information for {{ user_name }}{% endtrans %}
|
|
||||||
{%- endcall -%}
|
|
||||||
{%- call custom_form_button("passwd", reset_form.action_create.name, user.localpart, class="secondary", slim=True) -%}
|
|
||||||
{% trans user_name=user.localpart %}Create password reset link for {{ user_name }}{% endtrans %}
|
|
||||||
{%- endcall -%}
|
{%- endcall -%}
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
@@ -33,6 +25,5 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table></div>
|
</table></div>
|
||||||
</form>
|
|
||||||
{%- include "admin_create_invite_form.html" -%}
|
{%- include "admin_create_invite_form.html" -%}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -17,131 +17,157 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.9.0\n"
|
"Generated-By: Babel 2.9.0\n"
|
||||||
|
|
||||||
#: snikket_web/admin.py:62
|
#: snikket_web/admin.py:61 snikket_web/templates/admin_delete_user.html:10
|
||||||
msgid "Delete user permanently"
|
#: snikket_web/templates/admin_users.html:8
|
||||||
|
msgid "Login name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:75
|
#: snikket_web/admin.py:65 snikket_web/templates/admin_delete_user.html:12
|
||||||
msgid "User deleted"
|
#: snikket_web/templates/admin_users.html:9 snikket_web/user.py:61
|
||||||
|
msgid "Display name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:118
|
#: snikket_web/admin.py:69
|
||||||
|
msgid "Update user"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/admin.py:73
|
||||||
|
msgid "Create password reset link"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/admin.py:91
|
||||||
msgid "Password reset link created"
|
msgid "Password reset link created"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:124
|
#: snikket_web/admin.py:105
|
||||||
|
msgid "User information updated."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/admin.py:123
|
||||||
|
msgid "Delete user permanently"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/admin.py:136
|
||||||
|
msgid "User deleted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/admin.py:174
|
||||||
|
msgid "Password reset link not found"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/admin.py:186
|
||||||
msgid "Password reset link deleted"
|
msgid "Password reset link deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:143
|
#: snikket_web/admin.py:206
|
||||||
msgid "Invite to circle"
|
msgid "Invite to circle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:149
|
#: snikket_web/admin.py:212
|
||||||
msgid "At least one circle must be selected"
|
msgid "At least one circle must be selected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:154
|
#: snikket_web/admin.py:217
|
||||||
msgid "Valid for"
|
msgid "Valid for"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:156
|
#: snikket_web/admin.py:219
|
||||||
msgid "One hour"
|
msgid "One hour"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:157
|
#: snikket_web/admin.py:220
|
||||||
msgid "Twelve hours"
|
msgid "Twelve hours"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:158
|
#: snikket_web/admin.py:221
|
||||||
msgid "One day"
|
msgid "One day"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:159
|
#: snikket_web/admin.py:222
|
||||||
msgid "One week"
|
msgid "One week"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:160
|
#: snikket_web/admin.py:223
|
||||||
msgid "Four weeks"
|
msgid "Four weeks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:166 snikket_web/templates/admin_edit_invite.html:17
|
#: snikket_web/admin.py:229 snikket_web/templates/admin_edit_invite.html:17
|
||||||
msgid "Invitation type"
|
msgid "Invitation type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:168 snikket_web/templates/library.j2:116
|
#: snikket_web/admin.py:231 snikket_web/templates/library.j2:116
|
||||||
msgid "Individual"
|
msgid "Individual"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:169 snikket_web/templates/library.j2:114
|
#: snikket_web/admin.py:232 snikket_web/templates/library.j2:114
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:175
|
#: snikket_web/admin.py:238
|
||||||
msgid "New invitation link"
|
msgid "New invitation link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:237
|
#: snikket_web/admin.py:300
|
||||||
msgid "Revoke"
|
msgid "Revoke"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:261
|
#: snikket_web/admin.py:324
|
||||||
msgid "Invitation created"
|
msgid "Invitation created"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:277
|
#: snikket_web/admin.py:340
|
||||||
msgid "No such invitation exists"
|
msgid "No such invitation exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:292
|
#: snikket_web/admin.py:355
|
||||||
msgid "Invitation revoked"
|
msgid "Invitation revoked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:309 snikket_web/admin.py:357
|
#: snikket_web/admin.py:372 snikket_web/admin.py:420
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:314 snikket_web/templates/admin_circles.html:47
|
#: snikket_web/admin.py:377 snikket_web/templates/admin_circles.html:47
|
||||||
msgid "Create circle"
|
msgid "Create circle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:344
|
#: snikket_web/admin.py:407
|
||||||
msgid "Circle created"
|
msgid "Circle created"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:362
|
#: snikket_web/admin.py:425
|
||||||
msgid "Select user"
|
msgid "Select user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:367
|
#: snikket_web/admin.py:430
|
||||||
msgid "Update circle"
|
msgid "Update circle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:371
|
#: snikket_web/admin.py:434
|
||||||
msgid "Delete circle permanently"
|
msgid "Delete circle permanently"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:377
|
#: snikket_web/admin.py:440
|
||||||
msgid "Add user"
|
msgid "Add user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:393
|
#: snikket_web/admin.py:456
|
||||||
msgid "No such circle exists"
|
msgid "No such circle exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:430
|
#: snikket_web/admin.py:493
|
||||||
msgid "Circle data updated"
|
msgid "Circle data updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:436
|
#: snikket_web/admin.py:499
|
||||||
msgid "Circle deleted"
|
msgid "Circle deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:447
|
#: snikket_web/admin.py:510
|
||||||
msgid "User added to circle"
|
msgid "User added to circle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/admin.py:456
|
#: snikket_web/admin.py:519
|
||||||
msgid "User removed from circle"
|
msgid "User removed from circle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -234,11 +260,6 @@ msgstr ""
|
|||||||
msgid "Everyone"
|
msgid "Everyone"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/templates/admin_delete_user.html:12
|
|
||||||
#: snikket_web/templates/admin_users.html:11 snikket_web/user.py:61
|
|
||||||
msgid "Display name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: snikket_web/user.py:65
|
#: snikket_web/user.py:65
|
||||||
msgid "Avatar"
|
msgid "Avatar"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -384,7 +405,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: snikket_web/templates/admin_circles.html:15
|
#: snikket_web/templates/admin_circles.html:15
|
||||||
#: snikket_web/templates/admin_invites.html:24
|
#: snikket_web/templates/admin_invites.html:24
|
||||||
#: snikket_web/templates/admin_users.html:12
|
#: snikket_web/templates/admin_users.html:10
|
||||||
msgid "Actions"
|
msgid "Actions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -455,12 +476,12 @@ msgid "Copy complete output"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/templates/admin_delete_user.html:4
|
#: snikket_web/templates/admin_delete_user.html:4
|
||||||
#: snikket_web/templates/admin_users.html:22
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Delete user %(user_name)s"
|
msgid "Delete user %(user_name)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/templates/admin_delete_user.html:6
|
#: snikket_web/templates/admin_delete_user.html:6
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:22
|
||||||
msgid "Delete user"
|
msgid "Delete user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -468,11 +489,6 @@ msgstr ""
|
|||||||
msgid "Are you sure you want to delete the following user?"
|
msgid "Are you sure you want to delete the following user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/templates/admin_delete_user.html:10
|
|
||||||
#: snikket_web/templates/admin_users.html:10
|
|
||||||
msgid "Login name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: snikket_web/templates/admin_delete_user.html:15
|
#: snikket_web/templates/admin_delete_user.html:15
|
||||||
msgid "Danger"
|
msgid "Danger"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -610,6 +626,54 @@ msgstr ""
|
|||||||
msgid "Return to invitation list"
|
msgid "Return to invitation list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:4
|
||||||
|
#: snikket_web/templates/admin_users.html:20
|
||||||
|
#, python-format
|
||||||
|
msgid "Edit user %(user_name)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:7
|
||||||
|
msgid "Edit user"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:11
|
||||||
|
msgid "The login name cannot be changed."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:19
|
||||||
|
msgid "Return to user list"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:27
|
||||||
|
msgid "Further actions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:29
|
||||||
|
msgid "Reset password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:32
|
||||||
|
msgid ""
|
||||||
|
"If the user has lost their password, you can use the button below to "
|
||||||
|
"create a special link which allows to change the password of the account,"
|
||||||
|
" once."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:37
|
||||||
|
msgid "Debug information"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:39
|
||||||
|
msgid ""
|
||||||
|
"In some cases, extended information about the user account and the "
|
||||||
|
"connected devices is necessary to troubleshoot issues. The button below "
|
||||||
|
"reveals this (sensitive) information."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: snikket_web/templates/admin_edit_user.html:43
|
||||||
|
msgid "Show debug information"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/templates/admin_home.html:4
|
#: snikket_web/templates/admin_home.html:4
|
||||||
msgid "Welcome to the admin panel!"
|
msgid "Welcome to the admin panel!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -704,16 +768,6 @@ msgstr ""
|
|||||||
msgid "Destroy link"
|
msgid "Destroy link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: snikket_web/templates/admin_users.html:25
|
|
||||||
#, python-format
|
|
||||||
msgid "Show debug information for %(user_name)s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: snikket_web/templates/admin_users.html:28
|
|
||||||
#, python-format
|
|
||||||
msgid "Create password reset link for %(user_name)s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: snikket_web/templates/app.html:4
|
#: snikket_web/templates/app.html:4
|
||||||
msgid "Snikket Web Portal"
|
msgid "Snikket Web Portal"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
Reference in New Issue
Block a user