diff --git a/src/bornhack/urls.py b/src/bornhack/urls.py index ecb54200..7a681f75 100644 --- a/src/bornhack/urls.py +++ b/src/bornhack/urls.py @@ -305,6 +305,11 @@ urlpatterns = [ TeamLeaveView.as_view(), name='team_leave' ), + url( + r'(?P[-_\w+]+)/manage/$', + TeamManageView.as_view(), + name='team_manage' + ), # this has to be the last url in the list url( r'(?P[-_\w+]+)/$', diff --git a/src/camps/mixins.py b/src/camps/mixins.py index a529e0df..5234c1c7 100644 --- a/src/camps/mixins.py +++ b/src/camps/mixins.py @@ -3,12 +3,24 @@ from django.shortcuts import get_object_or_404 class CampViewMixin(object): + """ + This mixin makes sure self.camp is available (taken from url kwarg camp_slug) + It also filters out objects that belong to other camps when the queryset has + a direct relation to the Camp model. + """ def dispatch(self, request, *args, **kwargs): self.camp = get_object_or_404(Camp, slug=self.kwargs['camp_slug']) return super().dispatch(request, *args, **kwargs) def get_queryset(self): queryset = super(CampViewMixin, self).get_queryset() - return queryset.filter(camp=self.camp) + if queryset: + # check if we have a foreignkey to Camp, filter if so + for field in queryset.model._meta.fields: + if field.name=="camp" and field.related_model._meta.label == "camps.Camp": + return queryset.filter(camp=self.camp) + + # Camp relation not found, or queryset is empty, return it unaltered + return queryset diff --git a/src/teams/templates/team_detail.html b/src/teams/templates/team_detail.html index bc7e1a4a..66025522 100644 --- a/src/teams/templates/team_detail.html +++ b/src/teams/templates/team_detail.html @@ -9,7 +9,7 @@ Team: {{ team.name }} | {{ block.super }} {% block content %} -

{{ team.name }} Team

+

{{ team.name }} Team ({{ team.area.name }} area)

{{ team.description|unsafecommonmark }}

Currently {{ team.members.count }} people are members of this team{% if request.user in team.members.all %} (including you){% endif %}.

@@ -26,73 +26,16 @@ Team: {{ team.name }} | {{ block.super }} {% endif %} {% endif %} +{% if request.user in team.responsible.all %} + Manage Team +{% endif %}
-

{{ team.area.name }} Area:

-

This team is under the {{ team.area.name }} area. The following people are responsible for the {{ team.name }} team:

+

Team Responsible

+

The following people are responsible for the {{ team.name }} team:

-
- -{% if request.user in team.responsible %} - -

Manage {{ team.name }} Team

-
- {% csrf_token %} - - {% bootstrap_form form %} - -
- - {% buttons %} - - {% endbuttons %} -
- -
-
- - - - - - {% for membership in team.teammember_set.all %} - - {% else %} diff --git a/src/teams/templates/team_manage.html b/src/teams/templates/team_manage.html new file mode 100644 index 00000000..f06b6d94 --- /dev/null +++ b/src/teams/templates/team_manage.html @@ -0,0 +1,61 @@ +{% extends 'base.html' %} +{% load commonmark %} +{% load teams_tags %} +{% load bootstrap3 %} + +{% block title %} +Manage Team: {{ team.name }} | {{ block.super }} +{% endblock %} + +{% block content %} +

Manage {{ team.name }} Team

+ + {% csrf_token %} + + {% bootstrap_form form %} + + + {% buttons %} + + {% endbuttons %} + + +

{{ team.name }} Team Members

+
- Profile - - Name - - Email - - Description - - Membership Status - - Action - -
- {{ membership.user }} - - {{ membership.user.profile.name }} - - {{ membership.user.profile.email }} - - {{ membership.user.profile.description }} - - {% if membership.approved %}member{% else %}pending{% endif %} - - {% if membership.approved %} - Remove - {% else %} - Remove - Approve - {% endif %} - {% endfor %} - -{% endif %} - {% endblock %} diff --git a/src/teams/templates/team_list.html b/src/teams/templates/team_list.html index b9ee90c7..492c74f0 100644 --- a/src/teams/templates/team_list.html +++ b/src/teams/templates/team_list.html @@ -62,11 +62,15 @@ Teams | {{ block.super }} {% if request.user in team.members.all %} Leave {% else %} - {% if team.needs_members %} - Join - {% else %} - Team does not need members + {% if team.needs_members %} + Join + {% else %} + Team does not need members + {% endif %} {% endif %} + + {% if request.user in team.responsible.all %} + Manage {% endif %}
+ + + + {% for membership in team.teammember_set.all %} + +
+ Profile + + Name + + Email + + Description + + Membership + + Action + +
+ {{ membership.user }} + + {{ membership.user.profile.name }} + + {{ membership.user.profile.email }} + + {{ membership.user.profile.description }} + + {% if membership.approved %}member{% else %}pending{% endif %} + + {% if membership.approved %} + Remove + {% else %} + Remove + Approve + {% endif %} + {% endfor %} +{% endblock %} diff --git a/src/teams/views.py b/src/teams/views.py index a87155c9..3d0edcfe 100644 --- a/src/teams/views.py +++ b/src/teams/views.py @@ -14,17 +14,38 @@ import logging logger = logging.getLogger("bornhack.%s" % __name__) +class EnsureTeamResponsibleMixin(SingleObjectMixin): + model = Team + + def dispatch(self, request, *args, **kwargs): + if request.user not in self.get_object().responsible.all(): + messages.error(request, 'No thanks') + return redirect('team_detail', camp_slug=self.camp.slug, slug=self.get_object().slug) + + return super().dispatch( + request, *args, **kwargs + ) + + class TeamListView(CampViewMixin, ListView): template_name = "team_list.html" model = Team context_object_name = 'teams' -class TeamDetailView(CampViewMixin, DetailView, UpdateView, FormView): +class TeamDetailView(CampViewMixin, DetailView): template_name = "team_detail.html" - model = Team - form_class = ManageTeamForm context_object_name = 'team' + model = Team + + +class TeamManageView(CampViewMixin, EnsureTeamResponsibleMixin, UpdateView): + model = Team + template_name = "team_manage.html" + fields = ['description', 'needs_members'] + + def get_success_url(self): + return reverse_lazy('team_detail', kwargs={'camp_slug': self.camp.slug, 'slug': self.get_object().slug}) class TeamJoinView(LoginRequiredMixin, CampViewMixin, UpdateView): @@ -67,20 +88,20 @@ class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView): return redirect('team_list', camp_slug=self.get_object().camp.slug) -class EnsureTeamResponsibleMixin(SingleObjectMixin): +class EnsureTeamMemberResponsibleMixin(SingleObjectMixin): model = TeamMember def dispatch(self, request, *args, **kwargs): if request.user not in self.get_object().team.responsible.all(): messages.error(request, 'No thanks') - return HttpResponseRedirect(reverse_lazy('team_detail', slug=self.get_object().team.slug)) + return redirect('team_detail', camp_slug=self.get_object().team.camp.slug, slug=self.get_object().team.slug) return super().dispatch( request, *args, **kwargs ) -class TeamMemberRemoveView(LoginRequiredMixin, EnsureTeamResponsibleMixin, UpdateView): +class TeamMemberRemoveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView): template_name = "teammember_remove.html" model = TeamMember fields = [] @@ -94,10 +115,10 @@ class TeamMemberRemoveView(LoginRequiredMixin, EnsureTeamResponsibleMixin, Updat logger.error( 'Unable to add removed email to outgoing queue for teammember: {}'.format(form.instance) ) - return redirect('team_detail', camp_slug=form.instance.team.camp.slug, slug=form.instance.team.slug) + return redirect('team_detail', camp_slug=self.camp.slug, slug=form.instance.team.slug) -class TeamMemberApproveView(LoginRequiredMixin, EnsureTeamResponsibleMixin, UpdateView): +class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView): template_name = "teammember_approve.html" model = TeamMember fields = [] @@ -112,4 +133,5 @@ class TeamMemberApproveView(LoginRequiredMixin, EnsureTeamResponsibleMixin, Upda logger.error( 'Unable to add approved email to outgoing queue for teammember: {}'.format(form.instance) ) - return redirect('team_detail', camp_slug=form.instance.team.camp.slug, slug=form.instance.team.slug) + return redirect('team_detail', camp_slug=self.camp.slug, slug=form.instance.team.slug) +