diff --git a/club/static/bundled/club/role-list-index.ts b/club/static/bundled/club/role-list-index.ts index a750501a..2020bba4 100644 --- a/club/static/bundled/club/role-list-index.ts +++ b/club/static/bundled/club/role-list-index.ts @@ -3,16 +3,22 @@ import type { AlpineComponent } from "alpinejs"; interface RoleGroupData { isBoard: boolean; isPresidency: boolean; + roleId: number; } document.addEventListener("alpine:init", () => { - Alpine.data("clubRoleList", () => ({ + Alpine.data("clubRoleList", (config: { userRoleId: number | null }) => ({ + confirmOnSubmit: false, + /** * Edit relevant item data after it has been moved by x-sort */ reorder(item: AlpineComponent, conf: RoleGroupData) { item.isBoard = conf.isBoard; item.isPresidency = conf.isPresidency; + // if the user has moved its own role outside the presidency, + // submitting the form will require a confirmation + this.confirmOnSubmit = config.userRoleId === item.roleId && !item.isPresidency; this.resetOrder(); }, /** @@ -33,5 +39,23 @@ document.addEventListener("alpine:init", () => { elem.value = (i + 1).toString(); } }, + + /** + * If the user moved its role out of the presidency, ask a confirmation + * before submitting the form + */ + confirmSubmission(event: SubmitEvent) { + if ( + this.confirmOnSubmit && + !confirm( + gettext( + "You're going to remove your own role from the presidency. " + + "You may lock yourself out of this page. Do you want to continue ? ", + ), + ) + ) { + event.preventDefault(); + } + }, })); }); diff --git a/club/templates/club/club_roles.jinja b/club/templates/club/club_roles.jinja index 8c146401..998eb9fb 100644 --- a/club/templates/club/club_roles.jinja +++ b/club/templates/club/club_roles.jinja @@ -14,6 +14,7 @@ x-data="{ isPresidency: {{ subform.is_presidency.value()|lower }}, isBoard: {{ subform.is_board.value()|lower }}, + roleId: {{ subform.id.value() }}, }" x-sort:item="$data" > @@ -68,7 +69,11 @@ (e.g. a board role can be made into a presidency role). {% endtrans %}

-
+ {% csrf_token %} {{ form.management_form }} {{ form.non_form_errors() }} @@ -91,7 +96,6 @@
{% for subform in form %} {% if subform.is_presidency.value() %} @@ -125,7 +129,6 @@
{% for subform in form %} {% if subform.is_board.value() and not subform.is_presidency.value() %} @@ -144,7 +147,6 @@
{% for subform in form %} {% if not subform.is_board.value() %} diff --git a/club/views.py b/club/views.py index 68660212..2bb4ce9d 100644 --- a/club/views.py +++ b/club/views.py @@ -431,12 +431,10 @@ class ClubRoleUpdateView( success_message = _("Club roles updated") def test_func(self): - if self.request.user.has_perm("club.change_clubrole"): - return True - club: Club = self.get_object() - return club.members.filter( - user=self.request.user, role__is_presidency=True - ).exists() + return ( + self.request.user.is_authenticated + and self.get_object().can_roles_be_edited_by(self.request.user) + ) def get_form_kwargs(self): return super().get_form_kwargs() | {"form_kwargs": {"label_suffix": ""}} @@ -444,6 +442,17 @@ class ClubRoleUpdateView( def get_success_url(self): return self.request.path + def get_context_data(self, **kwargs): + return super().get_context_data(**kwargs) | { + "user_role": ClubRole.objects.filter( + club=self.object, + members__user=self.request.user, + members__end_date=None, + ) + .values_list("id", flat=True) + .first() + } + class ClubRoleBaseCreateView(UserPassesTestMixin, SuccessMessageMixin, CreateView): """View to create a new Club Role, using [][club.forms.ClubRoleCreateForm].