diff --git a/src/info/admin.py b/src/info/admin.py
index 941ac13a..9db9c82d 100644
--- a/src/info/admin.py
+++ b/src/info/admin.py
@@ -1,4 +1,5 @@
from django.contrib import admin
+from reversion.admin import VersionAdmin
from .models import (
InfoItem,
InfoCategory
@@ -6,7 +7,7 @@ from .models import (
@admin.register(InfoItem)
-class InfoItemAdmin(admin.ModelAdmin):
+class InfoItemAdmin(VersionAdmin):
list_filter = ['category', 'category__camp',]
list_display = ['headline',]
diff --git a/src/info/models.py b/src/info/models.py
index f86c60b1..75bddf20 100644
--- a/src/info/models.py
+++ b/src/info/models.py
@@ -37,6 +37,7 @@ class InfoCategory(CampRelatedModel):
blank=True,
help_text='The team responsible for this info category.',
on_delete=models.PROTECT,
+ related_name='info_categories'
)
def clean(self):
diff --git a/src/teams/models.py b/src/teams/models.py
index 03b8968b..0fd90245 100644
--- a/src/teams/models.py
+++ b/src/teams/models.py
@@ -109,6 +109,9 @@ class Team(CampRelatedModel):
def __str__(self):
return '{} ({})'.format(self.name, self.camp)
+ def get_absolute_url(self):
+ return reverse_lazy('teams:detail', kwargs={'camp_slug': self.camp.slug, 'team_slug': self.slug})
+
def save(self, **kwargs):
# generate slug if needed
if not self.pk or not self.slug:
diff --git a/src/teams/templates/info_item_form.html b/src/teams/templates/info_item_form.html
new file mode 100644
index 00000000..465671db
--- /dev/null
+++ b/src/teams/templates/info_item_form.html
@@ -0,0 +1,35 @@
+{% extends 'base.html' %}
+{% load commonmark %}
+{% load bootstrap3 %}
+
+{% block title %}
+{% if form.instance.id %}
+Edit Info Item: {{ form.instance.headline }}
+{% else %}
+Create Info item
+{% endif %}
+for in {{ form.instance.category.headline }}
+{% endblock %}
+
+{% block content %}
+
+
+
+ {% if form.instance.id %}
+ Edit Info Item: {{ form.instance.name }}
+ {% else %}
+ Create Info Item
+ {% endif %}
+ for in {{ form.instance.category.headline }}
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/src/teams/templates/team_detail.html b/src/teams/templates/team_detail.html
index 9d581363..86a96040 100644
--- a/src/teams/templates/team_detail.html
+++ b/src/teams/templates/team_detail.html
@@ -115,6 +115,41 @@ Team: {{ team.name }} | {{ block.super }}
{% if request.user in team.responsible_members.all %}
Create Task
{% endif %}
+
+ {# Team info categories section - only visible for team responsible #}
+ {% if request.user in team.responsible_members.all %}
+
+
+ Info categories
+
+ {% for info_category in team.info_categories.all %}
+
+ {{ info_category.headline }}
+
+
+
+ Item name |
+ Action |
+
+
+
+ {% for item in info_category.infoitems.all %}
+
+ {{ item.headline }} |
+
+
+ Edit Task
+
+ |
+
+ {% endfor %}
+
+
+
+ {% endfor %}
+
+ {% endif %}
diff --git a/src/teams/urls.py b/src/teams/urls.py
index eecc5acc..555bc945 100644
--- a/src/teams/urls.py
+++ b/src/teams/urls.py
@@ -1,6 +1,22 @@
from django.conf.urls import url, include
-from .views import *
+from teams.views.base import (
+ TeamListView,
+ TeamMemberRemoveView,
+ TeamMemberApproveView,
+ TeamDetailView,
+ TeamJoinView,
+ TeamLeaveView,
+ TeamManageView,
+ FixIrcAclView,
+)
+from teams.views.info import InfoItemUpdateView
+
+from teams.views.tasks import (
+ TaskCreateView,
+ TaskDetailView,
+ TaskUpdateView,
+)
app_name = 'teams'
@@ -75,6 +91,24 @@ urlpatterns = [
]),
),
+ url(
+ r'^info_items/', include([
+ url(
+ r'^(?P[-_\w+]+)/', include([
+ # url(
+ # r'^$',
+ # TaskDetailView.as_view(),
+ # name='task_detail',
+ # ),
+ url(
+ r'^update/$',
+ InfoItemUpdateView.as_view(),
+ name='info_item_update',
+ ),
+ ]),
+ ),
+ ])
+ )
]),
),
]
diff --git a/src/teams/views/__init__.py b/src/teams/views/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/teams/views.py b/src/teams/views/base.py
similarity index 73%
rename from src/teams/views.py
rename to src/teams/views/base.py
index f47b33c7..4ede5bd3 100644
--- a/src/teams/views.py
+++ b/src/teams/views/base.py
@@ -1,52 +1,22 @@
from django.views.generic import ListView, DetailView
-from django.views.generic.edit import CreateView, UpdateView
+from django.views.generic.edit import UpdateView
from camps.mixins import CampViewMixin
-from .models import Team, TeamMember, TeamTask
-from .email import add_added_membership_email, add_removed_membership_email
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import redirect
from django.contrib import messages
-from django.http import HttpResponseRedirect
-from django.views.generic.detail import SingleObjectMixin
from django.urls import reverse_lazy
from django.conf import settings
+
from profiles.models import Profile
+from .mixins import EnsureTeamResponsibleMixin, EnsureTeamMemberResponsibleMixin
+from ..models import Team, TeamMember
+from ..email import add_added_membership_email, add_removed_membership_email
+
import logging
logger = logging.getLogger("bornhack.%s" % __name__)
-class EnsureTeamResponsibleMixin(object):
- """
- Use to make sure request.user is responsible for the team specified by kwargs['team_slug']
- """
- def dispatch(self, request, *args, **kwargs):
- self.team = Team.objects.get(slug=kwargs['team_slug'], camp=self.camp)
- if request.user not in self.team.responsible_members.all():
- messages.error(request, 'No thanks')
- return redirect('teams:detail', camp_slug=self.camp.slug, team_slug=self.team.slug)
-
- return super().dispatch(
- request, *args, **kwargs
- )
-
-
-class EnsureTeamMemberResponsibleMixin(SingleObjectMixin):
- """
- Use to make sure request.user is responsible for the team which TeamMember belongs to
- """
- model = TeamMember
-
- def dispatch(self, request, *args, **kwargs):
- if request.user not in self.get_object().team.responsible_members.all():
- messages.error(request, 'No thanks')
- return redirect('teams:detail', camp_slug=self.get_object().team.camp.slug, team_slug=self.get_object().team.slug)
-
- return super().dispatch(
- request, *args, **kwargs
- )
-
-
class TeamListView(CampViewMixin, ListView):
template_name = "team_list.html"
model = Team
@@ -165,56 +135,6 @@ class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberR
return redirect('teams:detail', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
-class TaskDetailView(CampViewMixin, DetailView):
- template_name = "task_detail.html"
- context_object_name = "task"
- model = TeamTask
-
-
-class TaskCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, CreateView):
- model = TeamTask
- template_name = "task_form.html"
- fields = ['name', 'description']
-
- def get_context_data(self, *args, **kwargs):
- context = super().get_context_data(**kwargs)
- context['team'] = self.team
- return context
-
- def form_valid(self, form):
- task = form.save(commit=False)
- task.team = self.team
- if not task.name:
- task.name = "noname"
- task.save()
- return HttpResponseRedirect(task.get_absolute_url())
-
- def get_success_url(self):
- return self.get_object().get_absolute_url()
-
-
-class TaskUpdateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, UpdateView):
- model = TeamTask
- template_name = "task_form.html"
- fields = ['name', 'description']
-
- def get_context_data(self, *args, **kwargs):
- context = super().get_context_data(**kwargs)
- context['team'] = self.team
- return context
-
- def form_valid(self, form):
- task = form.save(commit=False)
- task.team = self.team
- if not task.name:
- task.name = "noname"
- task.save()
- return HttpResponseRedirect(task.get_absolute_url())
-
- def get_success_url(self):
- return self.get_object().get_absolute_url()
-
-
class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
template_name = "fix_irc_acl.html"
model = Team
diff --git a/src/teams/views/info.py b/src/teams/views/info.py
new file mode 100644
index 00000000..64c77916
--- /dev/null
+++ b/src/teams/views/info.py
@@ -0,0 +1,39 @@
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.views.generic import CreateView, UpdateView
+from reversion.views import RevisionMixin
+
+from camps.mixins import CampViewMixin
+from info.models import InfoItem
+from teams.views.mixins import EnsureTeamResponsibleMixin
+
+
+class InfoItemCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, CreateView):
+ model = InfoItem
+ template_name = "info_item_form.html"
+ fields = ['headline', 'body', 'anchor', 'weight']
+ slug_field = 'anchor'
+
+ def get_context_data(self, *args, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['team'] = self.object.category.team
+ return context
+
+ def get_success_url(self):
+ return self.object.category.team.get_absolute_url()
+
+
+class InfoItemUpdateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, RevisionMixin, UpdateView):
+ model = InfoItem
+ template_name = "info_item_form.html"
+ fields = ['headline', 'body', 'anchor', 'weight']
+ slug_field = 'anchor'
+ slug_url_kwarg = 'anchor'
+
+ def get_context_data(self, *args, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['team'] = self.object.category.team
+ return context
+
+ def get_success_url(self):
+ return self.object.category.team.get_absolute_url()
+
diff --git a/src/teams/views/mixins.py b/src/teams/views/mixins.py
new file mode 100644
index 00000000..db937891
--- /dev/null
+++ b/src/teams/views/mixins.py
@@ -0,0 +1,36 @@
+from django.contrib import messages
+from django.shortcuts import redirect
+from django.views.generic.detail import SingleObjectMixin
+
+from teams.models import Team, TeamMember
+
+
+class EnsureTeamResponsibleMixin(object):
+ """
+ Use to make sure request.user is responsible for the team specified by kwargs['team_slug']
+ """
+ def dispatch(self, request, *args, **kwargs):
+ self.team = Team.objects.get(slug=kwargs['team_slug'], camp=self.camp)
+ if request.user not in self.team.responsible_members.all():
+ messages.error(request, 'No thanks')
+ return redirect('teams:detail', camp_slug=self.camp.slug, team_slug=self.team.slug)
+
+ return super().dispatch(
+ request, *args, **kwargs
+ )
+
+
+class EnsureTeamMemberResponsibleMixin(SingleObjectMixin):
+ """
+ Use to make sure request.user is responsible for the team which TeamMember belongs to
+ """
+ model = TeamMember
+
+ def dispatch(self, request, *args, **kwargs):
+ if request.user not in self.get_object().team.responsible_members.all():
+ messages.error(request, 'No thanks')
+ return redirect('teams:detail', camp_slug=self.get_object().team.camp.slug, team_slug=self.get_object().team.slug)
+
+ return super().dispatch(
+ request, *args, **kwargs
+ )
\ No newline at end of file
diff --git a/src/teams/views/tasks.py b/src/teams/views/tasks.py
new file mode 100644
index 00000000..5e661df0
--- /dev/null
+++ b/src/teams/views/tasks.py
@@ -0,0 +1,57 @@
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.http import HttpResponseRedirect
+from django.views.generic import DetailView, CreateView, UpdateView
+
+from camps.mixins import CampViewMixin
+from ..models import TeamTask
+from .mixins import EnsureTeamResponsibleMixin
+
+
+class TaskDetailView(CampViewMixin, DetailView):
+ template_name = "task_detail.html"
+ context_object_name = "task"
+ model = TeamTask
+
+
+class TaskCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, CreateView):
+ model = TeamTask
+ template_name = "task_form.html"
+ fields = ['name', 'description']
+
+ def get_context_data(self, *args, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['team'] = self.team
+ return context
+
+ def form_valid(self, form):
+ task = form.save(commit=False)
+ task.team = self.team
+ if not task.name:
+ task.name = "noname"
+ task.save()
+ return HttpResponseRedirect(task.get_absolute_url())
+
+ def get_success_url(self):
+ return self.get_object().get_absolute_url()
+
+
+class TaskUpdateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, UpdateView):
+ model = TeamTask
+ template_name = "task_form.html"
+ fields = ['name', 'description']
+
+ def get_context_data(self, *args, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['team'] = self.team
+ return context
+
+ def form_valid(self, form):
+ task = form.save(commit=False)
+ task.team = self.team
+ if not task.name:
+ task.name = "noname"
+ task.save()
+ return HttpResponseRedirect(task.get_absolute_url())
+
+ def get_success_url(self):
+ return self.get_object().get_absolute_url()
\ No newline at end of file