* adds button and functionality for leaving a team
   * if the admin leaves the team, another user will be chosen as new admin automatically
* improves Team (django) admin backend
   * better control over user adding-removing
   * only added team members are selectable as admin
pull/150/head
mpeltriaux 3 years ago
parent 25d2b806ab
commit e029f8c61e

Binary file not shown.

@ -26,7 +26,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-12 10:28+0200\n" "POT-Creation-Date: 2022-04-13 15:13+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -154,7 +154,7 @@ msgstr "Geprüft"
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9 #: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9
#: analysis/templates/analysis/reports/includes/intervention/laws.html:20 #: analysis/templates/analysis/reports/includes/intervention/laws.html:20
#: analysis/templates/analysis/reports/includes/old_data/amount.html:18 #: analysis/templates/analysis/reports/includes/old_data/amount.html:18
#: compensation/tables.py:46 compensation/tables.py:222 #: compensation/tables.py:46 compensation/tables.py:220
#: compensation/templates/compensation/detail/compensation/view.html:78 #: compensation/templates/compensation/detail/compensation/view.html:78
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
#: compensation/templates/compensation/detail/eco_account/view.html:45 #: compensation/templates/compensation/detail/eco_account/view.html:45
@ -294,7 +294,7 @@ msgid "Intervention"
msgstr "Eingriff" msgstr "Eingriff"
#: analysis/templates/analysis/reports/includes/old_data/amount.html:34 #: analysis/templates/analysis/reports/includes/old_data/amount.html:34
#: compensation/tables.py:266 #: compensation/tables.py:264
#: compensation/templates/compensation/detail/eco_account/view.html:20 #: compensation/templates/compensation/detail/eco_account/view.html:20
#: intervention/forms/modalForms.py:348 intervention/forms/modalForms.py:355 #: intervention/forms/modalForms.py:348 intervention/forms/modalForms.py:355
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:4 #: konova/templates/konova/includes/quickstart/ecoaccounts.html:4
@ -315,7 +315,7 @@ msgid "Show only unrecorded"
msgstr "Nur unverzeichnete anzeigen" msgstr "Nur unverzeichnete anzeigen"
#: compensation/forms/forms.py:32 compensation/tables.py:25 #: compensation/forms/forms.py:32 compensation/tables.py:25
#: compensation/tables.py:197 ema/tables.py:29 intervention/forms/forms.py:28 #: compensation/tables.py:195 ema/tables.py:29 intervention/forms/forms.py:28
#: intervention/tables.py:24 #: intervention/tables.py:24
#: intervention/templates/intervention/detail/includes/compensations.html:30 #: intervention/templates/intervention/detail/includes/compensations.html:30
msgid "Identifier" msgid "Identifier"
@ -327,7 +327,7 @@ msgid "Generated automatically"
msgstr "Automatisch generiert" msgstr "Automatisch generiert"
#: compensation/forms/forms.py:44 compensation/tables.py:30 #: compensation/forms/forms.py:44 compensation/tables.py:30
#: compensation/tables.py:202 #: compensation/tables.py:200
#: compensation/templates/compensation/detail/compensation/includes/documents.html:28 #: compensation/templates/compensation/detail/compensation/includes/documents.html:28
#: compensation/templates/compensation/detail/compensation/view.html:32 #: compensation/templates/compensation/detail/compensation/view.html:32
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28
@ -675,22 +675,22 @@ msgstr ""
"Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen " "Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen "
"wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!" "wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!"
#: compensation/tables.py:35 compensation/tables.py:207 ema/tables.py:39 #: compensation/tables.py:35 compensation/tables.py:205 ema/tables.py:39
#: intervention/tables.py:34 konova/filters/mixins.py:98 #: intervention/tables.py:34 konova/filters/mixins.py:98
msgid "Parcel gmrkng" msgid "Parcel gmrkng"
msgstr "Gemarkung" msgstr "Gemarkung"
#: compensation/tables.py:52 compensation/tables.py:228 ema/tables.py:50 #: compensation/tables.py:52 compensation/tables.py:226 ema/tables.py:50
#: intervention/tables.py:51 #: intervention/tables.py:51
msgid "Editable" msgid "Editable"
msgstr "Freigegeben" msgstr "Freigegeben"
#: compensation/tables.py:58 compensation/tables.py:234 ema/tables.py:56 #: compensation/tables.py:58 compensation/tables.py:232 ema/tables.py:56
#: intervention/tables.py:57 #: intervention/tables.py:57
msgid "Last edit" msgid "Last edit"
msgstr "Zuletzt bearbeitet" msgstr "Zuletzt bearbeitet"
#: compensation/tables.py:89 compensation/tables.py:266 ema/tables.py:89 #: compensation/tables.py:89 compensation/tables.py:264 ema/tables.py:89
#: intervention/tables.py:88 #: intervention/tables.py:88
msgid "Open {}" msgid "Open {}"
msgstr "Öffne {}" msgstr "Öffne {}"
@ -713,32 +713,32 @@ msgstr "Am {} von {} geprüft worden"
msgid "Not recorded yet" msgid "Not recorded yet"
msgstr "Noch nicht verzeichnet" msgstr "Noch nicht verzeichnet"
#: compensation/tables.py:165 compensation/tables.py:326 ema/tables.py:136 #: compensation/tables.py:165 compensation/tables.py:324 ema/tables.py:136
#: intervention/tables.py:162 #: intervention/tables.py:162
msgid "Recorded on {} by {}" msgid "Recorded on {} by {}"
msgstr "Am {} von {} verzeichnet worden" msgstr "Am {} von {} verzeichnet worden"
#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159 #: compensation/tables.py:187 compensation/tables.py:346 ema/tables.py:157
#: intervention/tables.py:185 #: intervention/tables.py:183
msgid "Full access granted" msgid "Full access granted"
msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden" msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden"
#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159 #: compensation/tables.py:187 compensation/tables.py:346 ema/tables.py:157
#: intervention/tables.py:185 #: intervention/tables.py:183
msgid "Access not granted" msgid "Access not granted"
msgstr "Nicht freigegeben - Datensatz nur lesbar" msgstr "Nicht freigegeben - Datensatz nur lesbar"
#: compensation/tables.py:212 #: compensation/tables.py:210
#: compensation/templates/compensation/detail/eco_account/view.html:36 #: compensation/templates/compensation/detail/eco_account/view.html:36
#: konova/templates/konova/widgets/progressbar.html:3 #: konova/templates/konova/widgets/progressbar.html:3
msgid "Available" msgid "Available"
msgstr "Verfügbar" msgstr "Verfügbar"
#: compensation/tables.py:243 #: compensation/tables.py:241
msgid "Eco Accounts" msgid "Eco Accounts"
msgstr "Ökokonten" msgstr "Ökokonten"
#: compensation/tables.py:321 #: compensation/tables.py:319
msgid "Not recorded yet. Can not be used for deductions, yet." msgid "Not recorded yet. Can not be used for deductions, yet."
msgstr "" msgstr ""
"Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden." "Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden."
@ -1112,20 +1112,6 @@ msgstr "Maßnahmenträger"
msgid "Report" msgid "Report"
msgstr "Bericht" msgstr "Bericht"
#: compensation/templates/compensation/report/compensation/report.html:45
#: compensation/templates/compensation/report/eco_account/report.html:58
#: ema/templates/ema/report/report.html:45
#: intervention/templates/intervention/report/report.html:104
msgid "Open in browser"
msgstr "Im Browser öffnen"
#: compensation/templates/compensation/report/compensation/report.html:49
#: compensation/templates/compensation/report/eco_account/report.html:62
#: ema/templates/ema/report/report.html:49
#: intervention/templates/intervention/report/report.html:108
msgid "View in LANIS"
msgstr "In LANIS öffnen"
#: compensation/templates/compensation/report/eco_account/report.html:24 #: compensation/templates/compensation/report/eco_account/report.html:24
msgid "Deductions for" msgid "Deductions for"
msgstr "Abbuchungen für" msgstr "Abbuchungen für"
@ -1204,22 +1190,22 @@ msgstr "{} entzeichnet"
msgid "{} recorded" msgid "{} recorded"
msgstr "{} verzeichnet" msgstr "{} verzeichnet"
#: compensation/views/eco_account.py:792 ema/views.py:617 #: compensation/views/eco_account.py:796 ema/views.py:621
#: intervention/views.py:428 #: intervention/views.py:428
msgid "{} has already been shared with you" msgid "{} has already been shared with you"
msgstr "{} wurde bereits für Sie freigegeben" msgstr "{} wurde bereits für Sie freigegeben"
#: compensation/views/eco_account.py:797 ema/views.py:622 #: compensation/views/eco_account.py:801 ema/views.py:626
#: intervention/views.py:433 #: intervention/views.py:433
msgid "{} has been shared with you" msgid "{} has been shared with you"
msgstr "{} ist nun für Sie freigegeben" msgstr "{} ist nun für Sie freigegeben"
#: compensation/views/eco_account.py:804 ema/views.py:629 #: compensation/views/eco_account.py:808 ema/views.py:633
#: intervention/views.py:440 #: intervention/views.py:440
msgid "Share link invalid" msgid "Share link invalid"
msgstr "Freigabelink ungültig" msgstr "Freigabelink ungültig"
#: compensation/views/eco_account.py:827 ema/views.py:652 #: compensation/views/eco_account.py:831 ema/views.py:656
#: intervention/views.py:463 #: intervention/views.py:463
msgid "Share settings updated" msgid "Share settings updated"
msgstr "Freigabe Einstellungen aktualisiert" msgstr "Freigabe Einstellungen aktualisiert"
@ -1802,6 +1788,14 @@ msgstr "Neu"
msgid "Show" msgid "Show"
msgstr "Anzeigen" msgstr "Anzeigen"
#: konova/templates/konova/includes/report/qrcodes.html:7
msgid "Open in browser"
msgstr "Im Browser öffnen"
#: konova/templates/konova/includes/report/qrcodes.html:15
msgid "View in LANIS"
msgstr "In LANIS öffnen"
#: konova/templates/konova/widgets/checkbox-tree-select.html:4 #: konova/templates/konova/widgets/checkbox-tree-select.html:4
#: templates/generic_index.html:56 #: templates/generic_index.html:56
msgid "Search" msgid "Search"
@ -2451,9 +2445,9 @@ msgid ""
" " " "
msgstr "" msgstr ""
"\n" "\n"
" Diese Daten sind noch nicht veröffentlicht und/oder haben das Bestandskraftdatum noch nicht erreicht. " " Diese Daten sind noch nicht veröffentlicht und/oder haben das "
"Sie können daher aktuell nicht eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt " "Bestandskraftdatum noch nicht erreicht. Sie können daher aktuell nicht "
"wieder vorbei. \n" "eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt wieder vorbei. \n"
" " " "
#: templates/table/gmrkng_col.html:6 #: templates/table/gmrkng_col.html:6
@ -2504,11 +2498,11 @@ msgstr "Neuen Token generieren"
msgid "A new token needs to be validated by an administrator!" msgid "A new token needs to be validated by an administrator!"
msgstr "Neue Tokens müssen durch Administratoren freigeschaltet werden!" msgstr "Neue Tokens müssen durch Administratoren freigeschaltet werden!"
#: user/forms.py:168 user/forms.py:172 user/forms.py:323 user/forms.py:328 #: user/forms.py:168 user/forms.py:172 user/forms.py:332 user/forms.py:337
msgid "Team name" msgid "Team name"
msgstr "Team Name" msgstr "Team Name"
#: user/forms.py:179 user/forms.py:336 user/templates/user/team/index.html:30 #: user/forms.py:179 user/forms.py:345 user/templates/user/team/index.html:30
msgid "Description" msgid "Description"
msgstr "Beschreibung" msgstr "Beschreibung"
@ -2556,7 +2550,11 @@ msgstr "Gewählter Administrator ({}) muss ein Mitglied des Teams sein."
msgid "Edit team" msgid "Edit team"
msgstr "Team bearbeiten" msgstr "Team bearbeiten"
#: user/forms.py:347 #: user/forms.py:323 user/templates/user/team/index.html:58
msgid "Leave team"
msgstr "Team verlassen"
#: user/forms.py:356
msgid "Team" msgid "Team"
msgstr "Team" msgstr "Team"
@ -2702,6 +2700,14 @@ msgstr "Team bearbeitet"
msgid "Team removed" msgid "Team removed"
msgstr "Team gelöscht" msgstr "Team gelöscht"
#: user/views.py:218
msgid "You are not a member of this team"
msgstr "Sie sind kein Mitglied dieses Teams"
#: user/views.py:225
msgid "Left Team"
msgstr "Team verlassen"
#: venv/lib/python3.7/site-packages/bootstrap4/components.py:17 #: venv/lib/python3.7/site-packages/bootstrap4/components.py:17
#: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/form_errors.html:3 #: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/form_errors.html:3
#: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/messages.html:4 #: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/messages.html:4

@ -74,6 +74,15 @@ class TeamAdmin(admin.ModelAdmin):
"name", "name",
"description", "description",
] ]
filter_horizontal = [
"users"
]
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "admin":
team_id = request.resolver_match.kwargs.get("object_id", None)
kwargs["queryset"] = User.objects.filter(teams__id__in=[team_id])
return super().formfield_for_foreignkey(db_field, request, **kwargs)
admin.site.register(User, UserAdmin) admin.site.register(User, UserAdmin)

@ -317,6 +317,15 @@ class RemoveTeamModalForm(RemoveModalForm):
pass pass
class LeaveTeamModalForm(RemoveModalForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.form_title = _("Leave team")
def save(self):
self.instance.remove_user(self.user)
class TeamDataForm(BaseModalForm): class TeamDataForm(BaseModalForm):
name = forms.CharField( name = forms.CharField(
label_suffix="", label_suffix="",

@ -93,3 +93,17 @@ class Team(UuidModel):
""" """
mailer = Mailer() mailer = Mailer()
mailer.send_mail_shared_data_deleted_team(obj_identifier, obj_title, self) mailer.send_mail_shared_data_deleted_team(obj_identifier, obj_title, self)
def remove_user(self, user):
""" Removes a user from the team
Args:
user (User): The user to be removed
Returns:
"""
self.users.remove(user)
if self.admin == user:
self.admin = self.users.first()
self.save()

@ -46,6 +46,9 @@
{% endfor %} {% endfor %}
</td> </td>
<td> <td>
<button class="btn rlp-r btn-modal" data-form-url="{% url 'user:team-leave' team.id %}" title="{% trans 'Leave team' %}">
{% fa5_icon 'sign-out-alt' %}
</button>
{% if team.admin == user %} {% if team.admin == user %}
<button class="btn rlp-r btn-modal" data-form-url="{% url 'user:team-edit' team.id %}" title="{% trans 'Edit team' %}"> <button class="btn rlp-r btn-modal" data-form-url="{% url 'user:team-edit' team.id %}" title="{% trans 'Edit team' %}">
{% fa5_icon 'edit' %} {% fa5_icon 'edit' %}

@ -20,5 +20,6 @@ urlpatterns = [
path("team/<id>", data_team_view, name="team-data"), path("team/<id>", data_team_view, name="team-data"),
path("team/<id>/edit", edit_team_view, name="team-edit"), path("team/<id>/edit", edit_team_view, name="team-edit"),
path("team/<id>/remove", remove_team_view, name="team-remove"), path("team/<id>/remove", remove_team_view, name="team-remove"),
path("team/<id>/leave", leave_team_view, name="team-leave"),
] ]

@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.decorators import any_group_check, default_group_required from konova.decorators import any_group_check, default_group_required
from user.forms import UserNotificationForm, UserContactForm, UserAPITokenForm, NewTeamModalForm, EditTeamModalForm, \ from user.forms import UserNotificationForm, UserContactForm, UserAPITokenForm, NewTeamModalForm, EditTeamModalForm, \
RemoveTeamModalForm, TeamDataForm RemoveTeamModalForm, TeamDataForm, LeaveTeamModalForm
@login_required @login_required
@ -204,3 +204,24 @@ def remove_team_view(request: HttpRequest, id: str):
_("Team removed"), _("Team removed"),
redirect_url=reverse("user:team-index") redirect_url=reverse("user:team-index")
) )
@login_required
def leave_team_view(request: HttpRequest, id: str):
team = get_object_or_404(Team, id=id)
user = request.user
is_user_team_member = team.users.filter(id=user.id).exists()
if not is_user_team_member:
messages.info(
request,
_("You are not a member of this team")
)
return redirect("user:team-index")
form = LeaveTeamModalForm(request.POST or None, instance=team, request=request)
return form.process_request(
request,
_("Left Team"),
redirect_url=reverse("user:team-index")
)

Loading…
Cancel
Save