more work on tasks
This commit is contained in:
parent
d028c16966
commit
f725a5c941
|
@ -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()
|
||||||
|
|
||||||
|
|
20
src/teams/templates/task_create.html
Normal file
20
src/teams/templates/task_create.html
Normal 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 %}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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',
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue