more work on tasks

This commit is contained in:
Thomas Steen Rasmussen 2017-11-24 22:06:23 +01:00
parent d028c16966
commit f725a5c941
9 changed files with 108 additions and 51 deletions

View file

@ -150,3 +150,7 @@ class TeamTask(CampRelatedModel):
self.slug = slug self.slug = slug
super().save(**kwargs) super().save(**kwargs)
@property
def responsible(self):
return team.responsible.all()

View file

@ -0,0 +1,20 @@
{% extends 'base.html' %}
{% load commonmark %}
{% block title %}
Create Task for {{ task.team.name }} Team
{% endblock %}
{% block content %}
<div class="panel panel-default">
<div class="panel-heading"><h4>Create Task</h4></div>
<div class="panel-body">
<form method="POST">
{{ form }}
<button type="submit" class="btn btn-primary">
</form>
</div>
<div class="panel-footer"><i>This task belongs to the <a href="{% url 'teams:detail' slug=team.slug camp_slug=team.camp.slug %}">{{ team.name }} Team</a></i></div>
</div>
{% endblock %}

View file

@ -9,7 +9,7 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"><h4>Task: {{ task.name }}</h4></div> <div class="panel-heading"><h4>Task: {{ task.name }}</h4></div>
<div class="panel-body">{{ task.description|commonmark }}</div> <div class="panel-body">{{ task.description|commonmark }}</div>
<div class="panel-footer"><i>This task belongs to the <a href="{% url 'teams:detail' slug=task.team.slug camp_slug=task.team.camp.slug %}">{{ task.team.name }} Team</a></i></div> <div class="panel-footer"><i>This task belongs to the <a href="{% url 'teams:detail' team_slug=task.team.slug camp_slug=task.team.camp.slug %}">{{ task.team.name }} Team</a></i></div>
</div> </div>

View file

@ -14,7 +14,7 @@ Team: {{ team.name }} | {{ block.super }}
<div class="panel-body"> <div class="panel-body">
{{ team.description|unsafecommonmark }} {{ team.description|unsafecommonmark }}
{% if request.user in team.responsible.all %} {% if request.user in team.responsible.all %}
<a href="{% url 'teams:manage' camp_slug=camp.slug slug=team.slug %}" class="btn btn-success">Manage Team</a> <a href="{% url 'teams:manage' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-success">Manage Team</a>
{% endif %} {% endif %}
<hr> <hr>
@ -55,10 +55,10 @@ Team: {{ team.name }} | {{ block.super }}
{% endif %} {% endif %}
{% if request.user in team.members.all %} {% if request.user in team.members.all %}
<a href="{% url 'teams:leave' camp_slug=camp.slug slug=team.slug %}" class="btn btn-danger">Leave Team</a> <a href="{% url 'teams:leave' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-danger">Leave Team</a>
{% else %} {% else %}
{% if team.needs_members %} {% if team.needs_members %}
<b>This team is looking for members!</b> <a href="{% url 'teams:join' camp_slug=camp.slug slug=team.slug %}" class="btn btn-xs btn-success">Join Team</a> <b>This team is looking for members!</b> <a href="{% url 'teams:join' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-xs btn-success">Join Team</a>
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -33,7 +33,7 @@ Teams | {{ block.super }}
{% for team in teams %} {% for team in teams %}
<tr> <tr>
<td> <td>
<a href="{% url 'teams:detail' camp_slug=camp.slug slug=team.slug %}"> <a href="{% url 'teams:detail' camp_slug=camp.slug team_slug=team.slug %}">
{{ team.name }} Team {{ team.name }} Team
</a> </a>
</td> </td>
@ -72,15 +72,15 @@ Teams | {{ block.super }}
<td> <td>
{% if request.user in team.members.all %} {% if request.user in team.members.all %}
<a href="{% url 'teams:leave' camp_slug=camp.slug slug=team.slug %}" class="btn btn-danger"><i class="fa fa-minus"></i> Leave</a> <a href="{% url 'teams:leave' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-danger"><i class="fa fa-minus"></i> Leave</a>
{% else %} {% else %}
{% if team.needs_members %} {% if team.needs_members %}
<a href="{% url 'teams:join' camp_slug=camp.slug slug=team.slug %}" class="btn btn-success"><i class="fa fa-plus"></i> Join</a> <a href="{% url 'teams:join' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-success"><i class="fa fa-plus"></i> Join</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if request.user in team.responsible.all %} {% if request.user in team.responsible.all %}
<a href="{% url 'teams:manage' camp_slug=camp.slug slug=team.slug %}" class="btn btn-primary"><i class="fa fa-cog"></i> Manage</a> <a href="{% url 'teams:manage' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fa fa-cog"></i> Manage</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
</td> </td>

View file

@ -13,6 +13,6 @@ Approve team member {{ teammember.user.profile.name }} for the {{ teammember.tea
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Add teammember</button> <button class="btn btn-success" type="submit"><i class="fa fa-check"></i> Add teammember</button>
<a href="{% url 'teams:detail' camp_slug=teammember.team.camp.slug slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a> <a href="{% url 'teams:detail' camp_slug=teammember.team.camp.slug team_slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a>
</form> </form>
{% endblock %} {% endblock %}

View file

@ -13,6 +13,6 @@ Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.nam
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<button class="btn btn-danger" type="submit"><i class="fa fa-trash-o"></i> Remove teammember</button> <button class="btn btn-danger" type="submit"><i class="fa fa-trash-o"></i> Remove teammember</button>
<a href="{% url 'teams:detail' camp_slug=teammember.team.camp.slug slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a> <a href="{% url 'teams:detail' camp_slug=teammember.team.camp.slug team_slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fa fa-remove"></i> Cancel</a>
</form> </form>
{% endblock %} {% endblock %}

View file

@ -1,4 +1,4 @@
from django.conf.urls import url from django.conf.urls import url, include
from .views import * from .views import *
urlpatterns = [ urlpatterns = [
@ -8,40 +8,56 @@ urlpatterns = [
name='list' name='list'
), ),
url( url(
r'^members/(?P<pk>[0-9]+)/remove/$', r'^members/', include([
TeamMemberRemoveView.as_view(), url(
name='teammember_remove', r'^(?P<pk>[0-9]+)/remove/$',
TeamMemberRemoveView.as_view(),
name='teammember_remove',
),
url(
r'^(?P<pk>[0-9]+)/approve/$',
TeamMemberApproveView.as_view(),
name='teammember_approve',
),
]),
), ),
url( url(
r'^members/(?P<pk>[0-9]+)/approve/$', r'^(?P<team_slug>[-_\w+]+)/', include([
TeamMemberApproveView.as_view(), url(
name='teammember_approve', r'^$',
), TeamDetailView.as_view(),
url( name='detail'
r'(?P<team_slug>[-_\w+]+)/tasks/(?P<slug>[-_\w+]+)/$', ),
TaskDetailView.as_view(), url(
name='task_detail', r'^join/$',
), TeamJoinView.as_view(),
url( name='join'
r'(?P<slug>[-_\w+]+)/join/$', ),
TeamJoinView.as_view(), url(
name='join' r'^leave/$',
), TeamLeaveView.as_view(),
url( name='leave'
r'(?P<slug>[-_\w+]+)/leave/$', ),
TeamLeaveView.as_view(), url(
name='leave' r'^manage/$',
), TeamManageView.as_view(),
url( name='manage'
r'(?P<slug>[-_\w+]+)/manage/$', ),
TeamManageView.as_view(), url(
name='manage' r'^tasks/', include([
), url(
# this has to be the last url in the list r'^create/$',
url( TaskCreateView.as_view(),
r'(?P<slug>[-_\w+]+)/$', name='task_create',
TeamDetailView.as_view(), ),
name='detail' url(
r'^(?P<slug>[-_\w+]+)/$',
TaskDetailView.as_view(),
name='task_detail',
),
]),
),
]),
), ),
] ]

View file

@ -1,5 +1,5 @@
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, FormView from django.views.generic.edit import CreateView, UpdateView, FormView
from camps.mixins import CampViewMixin from camps.mixins import CampViewMixin
from .models import Team, TeamMember, TeamTask from .models import Team, TeamMember, TeamTask
from .forms import ManageTeamForm from .forms import ManageTeamForm
@ -18,12 +18,10 @@ logger = logging.getLogger("bornhack.%s" % __name__)
class EnsureTeamResponsibleMixin(SingleObjectMixin): class EnsureTeamResponsibleMixin(SingleObjectMixin):
model = Team
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if request.user not in self.get_object().responsible.all(): if request.user not in self.get_object().responsible.all():
messages.error(request, 'No thanks') messages.error(request, 'No thanks')
return redirect('team_detail', camp_slug=self.camp.slug, slug=self.get_object().slug) return redirect('teams:detail', camp_slug=self.camp.slug, team_slug=self.get_object().slug)
return super().dispatch( return super().dispatch(
request, *args, **kwargs request, *args, **kwargs
@ -40,21 +38,24 @@ class TeamDetailView(CampViewMixin, DetailView):
template_name = "team_detail.html" template_name = "team_detail.html"
context_object_name = 'team' context_object_name = 'team'
model = Team model = Team
slug_url_kwarg = 'team_slug'
class TeamManageView(CampViewMixin, EnsureTeamResponsibleMixin, UpdateView): class TeamManageView(CampViewMixin, EnsureTeamResponsibleMixin, UpdateView):
model = Team model = Team
template_name = "team_manage.html" template_name = "team_manage.html"
fields = ['description', 'needs_members'] fields = ['description', 'needs_members']
slug_url_kwarg = 'team_slug'
def get_success_url(self): def get_success_url(self):
return reverse_lazy('team_detail', kwargs={'camp_slug': self.camp.slug, 'slug': self.get_object().slug}) return reverse_lazy('teams:detail', kwargs={'camp_slug': self.camp.slug, 'slug': self.get_object().slug})
class TeamJoinView(LoginRequiredMixin, CampViewMixin, UpdateView): class TeamJoinView(LoginRequiredMixin, CampViewMixin, UpdateView):
template_name = "team_join.html" template_name = "team_join.html"
model = Team model = Team
fields = [] fields = []
slug_url_kwarg = 'team_slug'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if not Profile.objects.get(user=request.user).description: if not Profile.objects.get(user=request.user).description:
@ -84,6 +85,7 @@ class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView):
template_name = "team_leave.html" template_name = "team_leave.html"
model = Team model = Team
fields = [] fields = []
slug_url_kwarg = 'team_slug'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if request.user not in self.get_object().members.all(): if request.user not in self.get_object().members.all():
@ -104,7 +106,7 @@ class EnsureTeamMemberResponsibleMixin(SingleObjectMixin):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if request.user not in self.get_object().team.responsible.all(): if request.user not in self.get_object().team.responsible.all():
messages.error(request, 'No thanks') messages.error(request, 'No thanks')
return redirect('team_detail', camp_slug=self.get_object().team.camp.slug, slug=self.get_object().team.slug) return redirect('teams:detail', camp_slug=self.get_object().team.camp.slug, team_slug=self.get_object().team.slug)
return super().dispatch( return super().dispatch(
request, *args, **kwargs request, *args, **kwargs
@ -125,7 +127,7 @@ class TeamMemberRemoveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberRe
logger.error( logger.error(
'Unable to add removed email to outgoing queue for teammember: {}'.format(form.instance) 'Unable to add removed email to outgoing queue for teammember: {}'.format(form.instance)
) )
return redirect('team_detail', camp_slug=self.camp.slug, slug=form.instance.team.slug) return redirect('teams:detail', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView): class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView):
@ -143,7 +145,7 @@ class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberR
logger.error( logger.error(
'Unable to add approved email to outgoing queue for teammember: {}'.format(form.instance) 'Unable to add approved email to outgoing queue for teammember: {}'.format(form.instance)
) )
return redirect('team_detail', camp_slug=self.camp.slug, slug=form.instance.team.slug) return redirect('teams:detail', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
class TaskDetailView(CampViewMixin, DetailView): class TaskDetailView(CampViewMixin, DetailView):
@ -151,3 +153,18 @@ class TaskDetailView(CampViewMixin, DetailView):
context_object_name = "task" context_object_name = "task"
model = TeamTask model = TeamTask
class TaskCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, CreateView):
model = TeamTask
template_name = "task_create.html"
fields = ['name', 'description']
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(**kwargs)
self.team = Team.objects.get(slug=kwargs['team_slug'], camp=self.camp)
context['team'] = self.team
return context
def get_success_url(self):
return reverse_lazy('task_detail', kwargs={'camp_slug': self.camp.slug, 'team_slug': self.team.slug, 'slug': self.get_object().slug})