diff --git a/src/teams/templates/task_form.html b/src/teams/templates/task_form.html
index c03e64c6..69d7e603 100644
--- a/src/teams/templates/task_form.html
+++ b/src/teams/templates/task_form.html
@@ -1,4 +1,4 @@
-{% extends 'base.html' %}
+{% extends 'team_base.html' %}
{% load commonmark %}
{% load bootstrap3 %}
@@ -11,7 +11,7 @@ Create Task
for {{ team.name }} Team
{% endblock %}
-{% block content %}
+{% block team_content %}
@@ -30,7 +30,7 @@ for {{ team.name }} Team
{% if form.instance.id %}Save{% else %}Create{% endif %}
-
+
{% endblock %}
diff --git a/src/teams/templates/team_base.html b/src/teams/templates/team_base.html
new file mode 100644
index 00000000..8ef87216
--- /dev/null
+++ b/src/teams/templates/team_base.html
@@ -0,0 +1,77 @@
+{% extends 'base.html' %}
+{% load commonmark %}
+{% load bootstrap3 %}
+{% load teams_tags %}
+
+{% block title %}
+Team: {{ team.name }} | {{ block.super }}
+{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+
+
+
+ {% if request.user.is_authenticated %}
+
+ {% if request.user in team.members.all %}
+
Your membership status: {% membershipstatus user team %}
+
+ {% if request.user in team.responsible_members.all %}
+
Manage Team
+ {% endif %}
+
+ {% else %}
+ {% if team.needs_members %}
+
This team is looking for members! Join Team
+ {% endif %}
+ {% endif %}
+
+ {% endif %}
+
+
+
+
+ {% block team_content %}{% endblock %}
+
+
+
+
+{% endblock %}
diff --git a/src/teams/templates/team_detail.html b/src/teams/templates/team_detail.html
deleted file mode 100644
index 2caa8544..00000000
--- a/src/teams/templates/team_detail.html
+++ /dev/null
@@ -1,155 +0,0 @@
-{% extends 'base.html' %}
-{% load commonmark %}
-{% load bootstrap3 %}
-{% load teams_tags %}
-
-{% block title %}
-Team: {{ team.name }} | {{ block.super }}
-{% endblock %}
-
-{% block content %}
-
-
-
-
-
-
Description
-
-
- {{ team.description|untrustedcommonmark }}
-
-
-
-{# Team communications #}
-
-
-
Communication Channels
-
-
- {{ team.camp.title }} teams primarily use mailing lists and IRC to communicate. The
{{ team.name }} team can be contacted in the following ways:
-
-
Mailing List
- {% if team.mailing_list and request.user in team.approved_members.all %}
-
The {{ team.name }} Team mailinglist is {{ team.mailing_list }} {% if team.mailing_list_archive_public %}, and the archives are publicly available{% endif %}. You should sign up for the list if you haven't already.
- {% elif team.mailing_list and team.mailinglist_nonmember_posts %}
-
The {{ team.name }} Team mailinglist is {{ team.mailing_list }} {% if team.mailing_list_archive_public %}, and the archives are publicly available{% endif %}. You do not need to be a member of the list to post to it.
- {% else %}
-
The {{ team.name }} Team does not have a public mailing list, but it can be contacted through our main email info@bornhack.dk .
- {% endif %}
-
-
IRC Channel
- {% if team.public_irc_channel_name %}
-
The {{ team.name }} Team public IRC channel is {{ team.public_irc_channel_name }} on {{ IRCBOT_SERVER_HOSTNAME }} .
- {% else %}
-
The {{ team.name }} Team does not have a public IRC channel, but it can be reached through our main IRC channel {{ IRCBOT_PUBLIC_CHANNEL }} on {{ IRCBOT_SERVER_HOSTNAME }} .
- {% endif %}
-
- {% if request.user in team.approved_members.all and team.private_irc_channel_name %}
-
The {{ team.name }} Team private IRC channel is {{ team.private_irc_channel_name }} on {{ IRCBOT_SERVER_HOSTNAME }} .
- {% endif %}
-
-
-
-
-{% include 'includes/team_tasks.html' %}
-
-{# Team members #}
-
-
-
Members
-
-
-
The following {{ team.approved_members.count }} people {% if team.unapproved_members.count %}(and {{ team.unapproved_members.count }} pending){% endif %} are members of the {{ team.name }} Team :
-
-
-
-
- Name
-
-
- Status
-
-
-
-
- {% for teammember in team.memberships.all %}
-
-
- {{ teammember.user.profile.get_public_credit_name }} {% if teammember.user == request.user %}(this is you!){% endif %}
-
-
- Team {% if teammember.responsible %}Responsible{% else %}Member{% endif %}
- {% if not teammember.approved %}(pending approval){% endif %}
-
-
- {% endfor %}
-
-
-
-
Your membership status: {% membershipstatus user team %}
-
- {% if request.user in team.members.all %}
- {% if team.irc_channel and team.irc_channel_managed and request.user.profile.nickserv_username %}
-
Fix IRC ACL
- {% endif %}
-
Leave Team
- {% else %}
- {% if team.needs_members %}
-
This team is looking for members! Join Team
- {% endif %}
- {% endif %}
-
- {% if request.user in team.responsible_members.all %}
-
Manage Team
- {% endif %}
-
-
-
-
-
-{# Team info categories section - only visible for team responsible #}
-{% if request.user in team.responsible_members.all and team.info_categories.exists %}
-
-
-
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
-
-
-
- {% endfor %}
-
-
-
-
Create Info Item
-
-
-
- {% endfor %}
-
-
-
-{% endif %}
-
-{% endblock %}
diff --git a/src/teams/templates/team_general.html b/src/teams/templates/team_general.html
new file mode 100644
index 00000000..2c5bfc91
--- /dev/null
+++ b/src/teams/templates/team_general.html
@@ -0,0 +1,48 @@
+{% extends 'team_base.html' %}
+{% load commonmark %}
+{% load bootstrap3 %}
+{% load teams_tags %}
+
+
+{% block team_content %}
+
+
+
+
Description
+
+
+ {{ team.description|untrustedcommonmark }}
+
+
+
+{# Team communications #}
+
+
+
Communication Channels
+
+
+ {{ team.camp.title }} teams primarily use mailing lists and IRC to communicate. The
{{ team.name }} team can be contacted in the following ways:
+
+
Mailing List
+ {% if team.mailing_list and request.user in team.approved_members.all %}
+
The {{ team.name }} Team mailinglist is {{ team.mailing_list }} {% if team.mailing_list_archive_public %}, and the archives are publicly available{% endif %}. You should sign up for the list if you haven't already.
+ {% elif team.mailing_list and team.mailinglist_nonmember_posts %}
+
The {{ team.name }} Team mailinglist is {{ team.mailing_list }} {% if team.mailing_list_archive_public %}, and the archives are publicly available{% endif %}. You do not need to be a member of the list to post to it.
+ {% else %}
+
The {{ team.name }} Team does not have a public mailing list, but it can be contacted through our main email info@bornhack.dk .
+ {% endif %}
+
+
IRC Channel
+ {% if team.public_irc_channel_name %}
+
The {{ team.name }} Team public IRC channel is {{ team.public_irc_channel_name }} on {{ IRCBOT_SERVER_HOSTNAME }} .
+ {% else %}
+
The {{ team.name }} Team does not have a public IRC channel, but it can be reached through our main IRC channel {{ IRCBOT_PUBLIC_CHANNEL }} on {{ IRCBOT_SERVER_HOSTNAME }} .
+ {% endif %}
+
+ {% if request.user in team.approved_members.all and team.private_irc_channel_name %}
+
The {{ team.name }} Team private IRC channel is {{ team.private_irc_channel_name }} on {{ IRCBOT_SERVER_HOSTNAME }} .
+ {% endif %}
+
+
+
+{% endblock %}
diff --git a/src/teams/templates/team_info_categories.html b/src/teams/templates/team_info_categories.html
new file mode 100644
index 00000000..15f0900c
--- /dev/null
+++ b/src/teams/templates/team_info_categories.html
@@ -0,0 +1,48 @@
+{% extends 'team_base.html' %}
+{% load commonmark %}
+{% load bootstrap3 %}
+{% load teams_tags %}
+
+
+{% block team_content %}
+
+
+
+
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
+
+
+
+ {% endfor %}
+
+
+
+
Create Info Item
+
+
+
+ {% endfor %}
+
+
+
+{% endblock %}
diff --git a/src/teams/templates/info_item_delete_confirm.html b/src/teams/templates/team_info_item_delete_confirm.html
similarity index 93%
rename from src/teams/templates/info_item_delete_confirm.html
rename to src/teams/templates/team_info_item_delete_confirm.html
index fe9f2403..18e6e28b 100644
--- a/src/teams/templates/info_item_delete_confirm.html
+++ b/src/teams/templates/team_info_item_delete_confirm.html
@@ -1,4 +1,4 @@
-{% extends 'base.html' %}
+{% extends 'team_base.html' %}
{% load commonmark %}
{% load bootstrap3 %}
@@ -11,7 +11,7 @@ Create Info item
in {{ form.instance.category.headline }}
{% endblock %}
-{% block content %}
+{% block team_content %}
diff --git a/src/teams/templates/info_item_form.html b/src/teams/templates/team_info_item_form.html
similarity index 83%
rename from src/teams/templates/info_item_form.html
rename to src/teams/templates/team_info_item_form.html
index 03d56ddf..e062ae9d 100644
--- a/src/teams/templates/info_item_form.html
+++ b/src/teams/templates/team_info_item_form.html
@@ -1,26 +1,28 @@
-{% extends 'base.html' %}
+{% extends 'team_base.html' %}
{% load commonmark %}
{% load bootstrap3 %}
{% block title %}
{% if object %}
Editing "{{ object.headline }}"
+in "{{ form.instance.category.headline }}"
{% else %}
Create Info item
+in "{{ category.headline }}"
{% endif %}
-in "{{ form.instance.category.headline }}"
{% endblock %}
-{% block content %}
+{% block team_content %}
{% if object %}
Editing "{{ object.headline }}"
+ in "{{ object.category.headline }}"
{% else %}
Create Info Item
+ in "{{ category.headline }}"
{% endif %}
- in "{{ object.category.headline }}"
@@ -36,6 +38,6 @@ in "{{ form.instance.category.headline }}"
{% endif %}
-
+
{% endblock %}
diff --git a/src/teams/templates/team_join.html b/src/teams/templates/team_join.html
index 5b83f7e6..f231b7a3 100644
--- a/src/teams/templates/team_join.html
+++ b/src/teams/templates/team_join.html
@@ -1,11 +1,11 @@
-{% extends 'base.html' %}
+{% extends 'team_base.html' %}
{% load commonmark %}
{% block title %}
Join Team: {{ team.name }} | {{ block.super }}
{% endblock %}
-{% block content %}
+{% block team_content %}
Really join the {{ team.name }} Team for {{ team.camp.title }} ?
diff --git a/src/teams/templates/team_leave.html b/src/teams/templates/team_leave.html
index 8cbc37e1..7e345e3d 100644
--- a/src/teams/templates/team_leave.html
+++ b/src/teams/templates/team_leave.html
@@ -1,11 +1,11 @@
-{% extends 'base.html' %}
+{% extends 'team_base.html' %}
{% load commonmark %}
{% block title %}
Leave Team: {{ team.name }} | {{ block.super }}
{% endblock %}
-{% block content %}
+{% block team_content %}
Leave {{ team.name }} Team
Really leave the {{ team.name }} team?
diff --git a/src/teams/templates/team_list.html b/src/teams/templates/team_list.html
index d09f8217..c0a314da 100644
--- a/src/teams/templates/team_list.html
+++ b/src/teams/templates/team_list.html
@@ -33,7 +33,7 @@ Teams | {{ block.super }}
{% for team in teams %}
-
+
{{ team.name }} Team
@@ -63,7 +63,7 @@ Teams | {{ block.super }}
-
Details
+
Details
{% if request.user in team.responsible_members.all %}
Manage
{% endif %}
diff --git a/src/teams/templates/team_manage.html b/src/teams/templates/team_manage.html
index 5e9b701b..643f95bc 100644
--- a/src/teams/templates/team_manage.html
+++ b/src/teams/templates/team_manage.html
@@ -1,4 +1,4 @@
-{% extends 'base.html' %}
+{% extends 'team_base.html' %}
{% load commonmark %}
{% load bootstrap3 %}
@@ -6,7 +6,7 @@
Manage Team: {{ team.name }} | {{ block.super }}
{% endblock %}
-{% block content %}
+{% block team_content %}
Manage {{ team.name }} Team
@@ -18,85 +18,11 @@ Manage Team: {{ team.name }} | {{ block.super }}
{% buttons %}
Save Team
-
Cancel
+
Cancel
{% endbuttons %}
-
-
Manage {{ team.name }} Team Members
-
- {% if team.teammember_set.exists %}
-
-
-
-
- Username
-
-
- Name
-
-
- Email
-
-
- Description
-
-
- Public Credit Name
-
-
- Membership
-
-
- Action
-
-
-
-
- {% for membership in team.teammember_set.all %}
-
-
- {{ membership.user }}
-
-
- {{ membership.user.profile.name }}
-
-
- {{ membership.user.profile.email }}
-
-
- {{ membership.user.profile.description }}
-
-
- {{ membership.user.profile.public_credit_name|default:"N/A" }}
- {% if membership.user.profile.public_credit_name and not membership.user.profile.public_credit_name_approved %}(name not approved) {% endif %}
-
-
- {% if membership.approved %}member{% else %}pending{% endif %}
-
-
-
-
-
- {% endfor %}
-
-
- {% else %}
-
No members found!
- {% endif %}
-
-
-
-{% include 'includes/team_tasks.html' %}
-
{% endblock %}
-
-
diff --git a/src/teams/templates/team_members.html b/src/teams/templates/team_members.html
new file mode 100644
index 00000000..b3fef15a
--- /dev/null
+++ b/src/teams/templates/team_members.html
@@ -0,0 +1,86 @@
+{% extends 'team_base.html' %}
+{% load commonmark %}
+{% load bootstrap3 %}
+{% load teams_tags %}
+
+
+{% block team_content %}
+
+
+
+
Members
+
+
+
The following {{ team.approved_members.count }} people {% if team.unapproved_members.count %}(and {{ team.unapproved_members.count }} pending){% endif %} are members of the {{ team.name }} Team :
+
+
+
+
+ Name
+
+
+ Status
+
+ {% if request.user in team.responsible_members.all %}
+
+ Action
+
+ {% endif %}
+
+
+
+ {% for member in team.memberships.all %}
+ {% if member.approved or not member.approved and request.user in team.responsible_members.all %}
+
+
+ {{ member.user.profile.get_public_credit_name }} {% if member.user == request.user %}(this is you!){% endif %}
+
+
+ Team {% if member.responsible %}Responsible{% else %}Member{% endif %}
+ {% if not member.approved %}(pending approval){% endif %}
+
+ {% if request.user in team.responsible_members.all %}
+
+
+
+ {% endif %}
+
+ {% endif %}
+ {% empty %}
+ No members found!
+ {% endfor %}
+
+
+
+ {% if request.user.authorized %}
+
+
Your membership status: {% membershipstatus user team %}
+
+ {% if request.user in team.members.all %}
+ {% if team.irc_channel and team.irc_channel_managed and request.user.profile.nickserv_username %}
+
Fix IRC ACL
+ {% endif %}
+
Leave Team
+ {% else %}
+ {% if team.needs_members %}
+
This team is looking for members! Join Team
+ {% endif %}
+ {% endif %}
+ {% endif %}
+
+
+
+
+
+{% endblock %}
diff --git a/src/teams/templates/includes/team_tasks.html b/src/teams/templates/team_tasks.html
similarity index 91%
rename from src/teams/templates/includes/team_tasks.html
rename to src/teams/templates/team_tasks.html
index f285eef4..30acae88 100644
--- a/src/teams/templates/includes/team_tasks.html
+++ b/src/teams/templates/team_tasks.html
@@ -1,3 +1,10 @@
+{% extends 'team_base.html' %}
+{% load commonmark %}
+{% load bootstrap3 %}
+{% load teams_tags %}
+
+{% block team_content %}
+
Tasks
@@ -10,7 +17,7 @@
Name
Description
When
- Completed
+ Completed?
Action
@@ -41,4 +48,4 @@
{% endif %}
-
+{% endblock %}
diff --git a/src/teams/templates/teammember_approve.html b/src/teams/templates/teammember_approve.html
index 92afa84a..22ad3844 100644
--- a/src/teams/templates/teammember_approve.html
+++ b/src/teams/templates/teammember_approve.html
@@ -1,11 +1,11 @@
-{% extends 'base.html' %}
+{% extends 'team_base.html' %}
{% load commonmark %}
{% block title %}
Approve team member {{ teammember.user.profile.name }} for the {{ teammember.team.name }} team
{% endblock %}
-{% block content %}
+{% block team_content %}
Approve member {{ teammember.user.profile.name }} for the {{ teammember.team.name }} team
Really approve the user {{ teammember.user.profile.name }} for the {{ teammember.team.name }} team? The user will receive an email with a message.
@@ -13,6 +13,7 @@ Approve team member {{ teammember.user.profile.name }} for the {{ teammember.tea
{% csrf_token %}
{{ form }}
Add teammember
- Cancel
+ Cancel
+
{% endblock %}
diff --git a/src/teams/templates/teammember_remove.html b/src/teams/templates/teammember_remove.html
index 775e2577..222c9083 100644
--- a/src/teams/templates/teammember_remove.html
+++ b/src/teams/templates/teammember_remove.html
@@ -1,11 +1,11 @@
-{% extends 'base.html' %}
+{% extends 'team_base.html' %}
{% load commonmark %}
{% block title %}
Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.name }} team
{% endblock %}
-{% block content %}
+{% block team_content %}
Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.name }} team
Really remove the user {{ teammember.user.profile.name }} from the {{ teammember.team.name }} team? The user will receive an email with a message.
@@ -13,6 +13,6 @@ Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.nam
{% csrf_token %}
{{ form }}
Remove teammember
- Cancel
+ Cancel
{% endblock %}
diff --git a/src/teams/urls.py b/src/teams/urls.py
index 330adfb9..b4def544 100644
--- a/src/teams/urls.py
+++ b/src/teams/urls.py
@@ -2,17 +2,28 @@ from django.urls import path, include
from teams.views.base import (
TeamListView,
- TeamMemberRemoveView,
- TeamMemberApproveView,
- TeamDetailView,
- TeamJoinView,
- TeamLeaveView,
+ TeamGeneralView,
TeamManageView,
FixIrcAclView,
)
-from teams.views.info import InfoItemUpdateView, InfoItemCreateView, InfoItemDeleteView
+
+from teams.views.members import (
+ TeamMembersView,
+ TeamMemberRemoveView,
+ TeamMemberApproveView,
+ TeamJoinView,
+ TeamLeaveView,
+)
+
+from teams.views.info import (
+ InfoCategoriesListView,
+ InfoItemUpdateView,
+ InfoItemCreateView,
+ InfoItemDeleteView,
+)
from teams.views.tasks import (
+ TeamTasksView,
TaskCreateView,
TaskDetailView,
TaskUpdateView,
@@ -26,26 +37,12 @@ urlpatterns = [
TeamListView.as_view(),
name='list'
),
- path(
- 'members/', include([
- path(
- '/remove/',
- TeamMemberRemoveView.as_view(),
- name='teammember_remove',
- ),
- path(
- '/approve/',
- TeamMemberApproveView.as_view(),
- name='teammember_approve',
- ),
- ]),
- ),
path(
'/', include([
path(
'',
- TeamDetailView.as_view(),
- name='detail'
+ TeamGeneralView.as_view(),
+ name='general'
),
path(
'join/',
@@ -67,8 +64,32 @@ urlpatterns = [
FixIrcAclView.as_view(),
name='fix_irc_acl',
),
+ path(
+ 'members/', include([
+ path(
+ '',
+ TeamMembersView.as_view(),
+ name='members'
+ ),
+ path(
+ '/remove/',
+ TeamMemberRemoveView.as_view(),
+ name='member_remove',
+ ),
+ path(
+ '/approve/',
+ TeamMemberApproveView.as_view(),
+ name='member_approve',
+ ),
+ ]),
+ ),
path(
'tasks/', include([
+ path(
+ '',
+ TeamTasksView.as_view(),
+ name='tasks',
+ ),
path(
'create/',
TaskCreateView.as_view(),
@@ -92,26 +113,36 @@ urlpatterns = [
]),
),
path(
- 'info//', include([
+ 'info/',
+ include([
path(
- 'create/',
- InfoItemCreateView.as_view(),
- name='info_item_create',
+ '',
+ InfoCategoriesListView.as_view(),
+ name='info_categories'
),
path(
- '/', include([
+ '/', include([
path(
- 'update/',
- InfoItemUpdateView.as_view(),
- name='info_item_update',
+ 'create/',
+ InfoItemCreateView.as_view(),
+ name='info_item_create',
),
path(
- 'delete/',
- InfoItemDeleteView.as_view(),
- name='info_item_delete',
+ '/', include([
+ path(
+ 'update/',
+ InfoItemUpdateView.as_view(),
+ name='info_item_update',
+ ),
+ path(
+ 'delete/',
+ InfoItemDeleteView.as_view(),
+ name='info_item_delete',
+ ),
+ ]),
),
- ]),
- ),
+ ])
+ )
])
)
]),
diff --git a/src/teams/views/base.py b/src/teams/views/base.py
index 4ede5bd3..cce95e70 100644
--- a/src/teams/views/base.py
+++ b/src/teams/views/base.py
@@ -7,11 +7,8 @@ from django.contrib import messages
from django.urls import reverse_lazy
from django.conf import settings
-from profiles.models import Profile
-
-from .mixins import EnsureTeamResponsibleMixin, EnsureTeamMemberResponsibleMixin
+from .mixins import EnsureTeamResponsibleMixin
from ..models import Team, TeamMember
-from ..email import add_added_membership_email, add_removed_membership_email
import logging
logger = logging.getLogger("bornhack.%s" % __name__)
@@ -23,14 +20,15 @@ class TeamListView(CampViewMixin, ListView):
context_object_name = 'teams'
-class TeamDetailView(CampViewMixin, DetailView):
- template_name = "team_detail.html"
+class TeamGeneralView(CampViewMixin, DetailView):
+ template_name = "team_general.html"
context_object_name = 'team'
model = Team
slug_url_kwarg = 'team_slug'
+ active_menu = 'general'
def get_context_data(self, **kwargs):
- context = super(TeamDetailView, self).get_context_data(**kwargs)
+ context = super().get_context_data(**kwargs)
context['IRCBOT_SERVER_HOSTNAME'] = settings.IRCBOT_SERVER_HOSTNAME
context['IRCBOT_PUBLIC_CHANNEL'] = settings.IRCBOT_PUBLIC_CHANNEL
return context
@@ -39,102 +37,20 @@ class TeamDetailView(CampViewMixin, DetailView):
class TeamManageView(CampViewMixin, EnsureTeamResponsibleMixin, UpdateView):
model = Team
template_name = "team_manage.html"
- fields = ['description', 'needs_members', 'public_irc_channel_name', 'public_irc_channel_bot', 'public_irc_channel_managed', 'private_irc_channel_name', 'private_irc_channel_bot', 'private_irc_channel_managed']
+ fields = ['description', 'needs_members', 'public_irc_channel_name',
+ 'public_irc_channel_bot', 'public_irc_channel_managed',
+ 'private_irc_channel_name', 'private_irc_channel_bot',
+ 'private_irc_channel_managed']
slug_url_kwarg = 'team_slug'
def get_success_url(self):
- return reverse_lazy('teams:detail', kwargs={'camp_slug': self.camp.slug, 'team_slug': self.get_object().slug})
+ return reverse_lazy('teams:general', kwargs={'camp_slug': self.camp.slug, 'team_slug': self.get_object().slug})
def form_valid(self, form):
messages.success(self.request, "Team has been saved")
return super().form_valid(form)
-class TeamJoinView(LoginRequiredMixin, CampViewMixin, UpdateView):
- template_name = "team_join.html"
- model = Team
- fields = []
- slug_url_kwarg = 'team_slug'
-
- def get(self, request, *args, **kwargs):
- if not Profile.objects.get(user=request.user).description:
- messages.warning(
- request,
- "Please fill the description in your profile before joining a team"
- )
- return redirect('teams:list', camp_slug=self.camp.slug)
-
- if request.user in self.get_object().members.all():
- messages.warning(request, "You are already a member of this team")
- return redirect('teams:list', camp_slug=self.camp.slug)
-
- if not self.get_object().needs_members:
- messages.warning(request, "This team does not need members right now")
- return redirect('teams:list', camp_slug=self.get_object().camp.slug)
-
- return super().get(request, *args, **kwargs)
-
- def form_valid(self, form):
- TeamMember.objects.create(team=self.get_object(), user=self.request.user)
- messages.success(self.request, "You request to join the team %s has been registered, thank you." % self.get_object().name)
- return redirect('teams:list', camp_slug=self.get_object().camp.slug)
-
-
-class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView):
- template_name = "team_leave.html"
- model = Team
- fields = []
- slug_url_kwarg = 'team_slug'
-
- def get(self, request, *args, **kwargs):
- if request.user not in self.get_object().members.all():
- messages.warning(request, "You are not a member of this team")
- return redirect('teams:list', camp_slug=self.get_object().camp.slug)
-
- return super().get(request, *args, **kwargs)
-
- def form_valid(self, form):
- TeamMember.objects.filter(team=self.get_object(), user=self.request.user).delete()
- messages.success(self.request, "You are no longer a member of the team %s" % self.get_object().name)
- return redirect('teams:list', camp_slug=self.get_object().camp.slug)
-
-
-
-class TeamMemberRemoveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView):
- template_name = "teammember_remove.html"
- model = TeamMember
- fields = []
-
- def form_valid(self, form):
- form.instance.delete()
- if add_removed_membership_email(form.instance):
- messages.success(self.request, "Team member removed")
- else:
- messages.success(self.request, "Team member removed (unable to add email to outgoing queue).")
- logger.error(
- 'Unable to add removed email to outgoing queue for teammember: {}'.format(form.instance)
- )
- return redirect('teams:detail', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
-
-
-class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView):
- template_name = "teammember_approve.html"
- model = TeamMember
- fields = []
-
- def form_valid(self, form):
- form.instance.approved = True
- form.instance.save()
- if add_added_membership_email(form.instance):
- messages.success(self.request, "Team member approved")
- else:
- messages.success(self.request, "Team member removed (unable to add email to outgoing queue).")
- logger.error(
- 'Unable to add approved email to outgoing queue for teammember: {}'.format(form.instance)
- )
- return redirect('teams:detail', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
-
-
class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
template_name = "fix_irc_acl.html"
model = Team
@@ -151,17 +67,17 @@ class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
# check if the logged in user has an approved membership of this team
if request.user not in self.get_object().approved_members.all():
messages.error(request, 'No thanks')
- return redirect('teams:detail', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug)
+ return redirect('teams:general', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug)
# check if we manage the channel for this team
if not self.get_object().irc_channel or not self.get_object().irc_channel_managed:
messages.error(request, 'IRC functionality is disabled for this team, or the team channel is not managed by the bot')
- return redirect('teams:detail', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug)
+ return redirect('teams:general', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug)
# check if user has a nickserv username
if not request.user.profile.nickserv_username:
messages.error(request, 'Please go to your profile and set your NickServ username first. Make sure the account is registered with NickServ first!')
- return redirect('teams:detail', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug)
+ return redirect('teams:general', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug)
return response
@@ -177,7 +93,7 @@ class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
except TeamMember.DoesNotExist:
# this membership is already marked as membership.irc_channel_acl_ok=False, no need to do anything
messages.error(request, 'No need, this membership is already marked as irc_channel_acl_ok=False, so the bot will fix the ACL soon')
- return redirect('teams:detail', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug)
+ return redirect('teams:general', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug)
return super().get(
request, *args, **kwargs
@@ -195,5 +111,5 @@ class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
membership.irc_channel_acl_ok = False
membership.save()
messages.success(self.request, "OK, hang on while we fix the permissions for your NickServ user '%s' for IRC channel '%s'" % (self.request.user.profile.nickserv_username, form.instance.irc_channel_name))
- return redirect('teams:detail', camp_slug=form.instance.camp.slug, team_slug=form.instance.slug)
+ return redirect('teams:general', camp_slug=form.instance.camp.slug, team_slug=form.instance.slug)
diff --git a/src/teams/views/info.py b/src/teams/views/info.py
index 5a6efaaa..0d49162d 100644
--- a/src/teams/views/info.py
+++ b/src/teams/views/info.py
@@ -1,23 +1,39 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
-from django.views.generic import CreateView, UpdateView, DeleteView
+from django.views.generic import CreateView, UpdateView, DeleteView, ListView
from reversion.views import RevisionMixin
from camps.mixins import CampViewMixin
from info.models import InfoItem, InfoCategory
-from teams.views.mixins import EnsureTeamResponsibleMixin
+from ..models import Team
+from .mixins import EnsureTeamResponsibleMixin, TeamViewMixin
-class InfoItemCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, CreateView):
+class InfoCategoriesListView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, ListView):
+ model = InfoCategory
+ template_name = "team_info_categories.html"
+ slug_field = 'anchor'
+ active_menu = 'info_categories'
+
+ def get_team(self):
+ return Team.objects.get(
+ camp__slug=self.kwargs['camp_slug'],
+ slug=self.kwargs['team_slug']
+ )
+
+
+class InfoItemCreateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, CreateView):
model = InfoItem
- template_name = "info_item_form.html"
+ template_name = "team_info_item_form.html"
fields = ['headline', 'body', 'anchor', 'weight']
slug_field = 'anchor'
+ active_menu = 'info_categories'
- def get_context_data(self, *args, **kwargs):
- context = super().get_context_data(**kwargs)
- context['team'] = self.team
- return context
+ def get_team(self):
+ return Team.objects.get(
+ camp__slug=self.kwargs['camp_slug'],
+ slug=self.kwargs['team_slug']
+ )
def form_valid(self, form):
info_item = form.save(commit=False)
@@ -29,18 +45,28 @@ class InfoItemCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibl
def get_success_url(self):
return self.team.get_absolute_url()
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['category'] = InfoCategory.objects.get(
+ team__camp__slug=self.kwargs['camp_slug'],
+ anchor=self.kwargs['category_anchor']
+ )
+ return context
-class InfoItemUpdateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, RevisionMixin, UpdateView):
+
+class InfoItemUpdateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, RevisionMixin, UpdateView):
model = InfoItem
- template_name = "info_item_form.html"
+ template_name = "team_info_item_form.html"
fields = ['headline', 'body', 'anchor', 'weight']
slug_field = 'anchor'
slug_url_kwarg = 'item_anchor'
+ active_menu = 'info_categories'
- def get_context_data(self, *args, **kwargs):
- context = super().get_context_data(**kwargs)
- context['team'] = self.team
- return context
+ def get_team(self):
+ return Team.objects.get(
+ camp__slug=self.kwargs['camp_slug'],
+ slug=self.kwargs['team_slug']
+ )
def get_success_url(self):
next = self.request.GET.get('next')
@@ -49,11 +75,18 @@ class InfoItemUpdateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibl
return self.team.get_absolute_url()
-class InfoItemDeleteView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, RevisionMixin, DeleteView):
+class InfoItemDeleteView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, RevisionMixin, DeleteView):
model = InfoItem
- template_name = "info_item_delete_confirm.html"
+ template_name = "team_info_item_delete_confirm.html"
slug_field = 'anchor'
slug_url_kwarg = 'item_anchor'
+ active_menu = 'info_categories'
+
+ def get_team(self):
+ return Team.objects.get(
+ camp__slug=self.kwargs['camp_slug'],
+ slug=self.kwargs['team_slug']
+ )
def get_success_url(self):
next = self.request.GET.get('next')
diff --git a/src/teams/views/members.py b/src/teams/views/members.py
new file mode 100644
index 00000000..8d050504
--- /dev/null
+++ b/src/teams/views/members.py
@@ -0,0 +1,111 @@
+import logging
+
+from django.views.generic import DetailView, UpdateView
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.contrib import messages
+from django.shortcuts import redirect
+
+from ..models import Team, TeamMember
+from profiles.models import Profile
+from camps.mixins import CampViewMixin
+
+from .mixins import EnsureTeamMemberResponsibleMixin, TeamViewMixin
+from ..email import add_added_membership_email, add_removed_membership_email
+
+logger = logging.getLogger("bornhack.%s" % __name__)
+
+
+class TeamMembersView(CampViewMixin, DetailView):
+ template_name = "team_members.html"
+ context_object_name = 'team'
+ model = Team
+ slug_url_kwarg = 'team_slug'
+ active_menu = 'members'
+
+
+class TeamJoinView(LoginRequiredMixin, CampViewMixin, UpdateView):
+ template_name = "team_join.html"
+ model = Team
+ fields = []
+ slug_url_kwarg = 'team_slug'
+ active_menu = 'members'
+
+ def get(self, request, *args, **kwargs):
+ if not Profile.objects.get(user=request.user).description:
+ messages.warning(
+ request,
+ "Please fill the description in your profile before joining a team"
+ )
+ return redirect('teams:list', camp_slug=self.camp.slug)
+
+ if request.user in self.get_object().members.all():
+ messages.warning(request, "You are already a member of this team")
+ return redirect('teams:list', camp_slug=self.camp.slug)
+
+ if not self.get_object().needs_members:
+ messages.warning(request, "This team does not need members right now")
+ return redirect('teams:list', camp_slug=self.get_object().camp.slug)
+
+ return super().get(request, *args, **kwargs)
+
+ def form_valid(self, form):
+ TeamMember.objects.create(team=self.get_object(), user=self.request.user)
+ messages.success(self.request, "You request to join the team %s has been registered, thank you." % self.get_object().name)
+ return redirect('teams:list', camp_slug=self.get_object().camp.slug)
+
+
+class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView):
+ template_name = "team_leave.html"
+ model = Team
+ fields = []
+ slug_url_kwarg = 'team_slug'
+ active_menu = 'members'
+
+ def get(self, request, *args, **kwargs):
+ if request.user not in self.get_object().members.all():
+ messages.warning(request, "You are not a member of this team")
+ return redirect('teams:list', camp_slug=self.get_object().camp.slug)
+
+ return super().get(request, *args, **kwargs)
+
+ def form_valid(self, form):
+ TeamMember.objects.filter(team=self.get_object(), user=self.request.user).delete()
+ messages.success(self.request, "You are no longer a member of the team %s" % self.get_object().name)
+ return redirect('teams:list', camp_slug=self.get_object().camp.slug)
+
+
+class TeamMemberRemoveView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView):
+ template_name = "teammember_remove.html"
+ model = TeamMember
+ fields = []
+ active_menu = 'members'
+
+ def form_valid(self, form):
+ form.instance.delete()
+ if add_removed_membership_email(form.instance):
+ messages.success(self.request, "Team member removed")
+ else:
+ messages.success(self.request, "Team member removed (unable to add email to outgoing queue).")
+ logger.error(
+ 'Unable to add removed email to outgoing queue for teammember: {}'.format(form.instance)
+ )
+ return redirect('teams:general', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
+
+
+class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView):
+ template_name = "teammember_approve.html"
+ model = TeamMember
+ fields = []
+ active_menu = 'members'
+
+ def form_valid(self, form):
+ form.instance.approved = True
+ form.instance.save()
+ if add_added_membership_email(form.instance):
+ messages.success(self.request, "Team member approved")
+ else:
+ messages.success(self.request, "Team member removed (unable to add email to outgoing queue).")
+ logger.error(
+ 'Unable to add approved email to outgoing queue for teammember: {}'.format(form.instance)
+ )
+ return redirect('teams:general', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
diff --git a/src/teams/views/mixins.py b/src/teams/views/mixins.py
index db937891..34608b0e 100644
--- a/src/teams/views/mixins.py
+++ b/src/teams/views/mixins.py
@@ -13,7 +13,7 @@ class EnsureTeamResponsibleMixin(object):
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 redirect('teams:general', camp_slug=self.camp.slug, team_slug=self.team.slug)
return super().dispatch(
request, *args, **kwargs
@@ -29,8 +29,19 @@ class EnsureTeamMemberResponsibleMixin(SingleObjectMixin):
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 redirect('teams:general', 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
+ )
+
+
+class TeamViewMixin:
+
+ def get_team(self):
+ return self.get_object().team
+
+ def get_context_data(self, *args, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['team'] = self.get_team()
+ return context
diff --git a/src/teams/views/tasks.py b/src/teams/views/tasks.py
index ebd61398..aaaed31b 100644
--- a/src/teams/views/tasks.py
+++ b/src/teams/views/tasks.py
@@ -1,44 +1,74 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
from django.views.generic import DetailView, CreateView, UpdateView
+from django import forms
from camps.mixins import CampViewMixin
-from ..models import TeamTask
-from .mixins import EnsureTeamResponsibleMixin
+from ..models import Team, TeamTask
+from .mixins import EnsureTeamResponsibleMixin, TeamViewMixin
-class TaskDetailView(CampViewMixin, DetailView):
+class TeamTasksView(CampViewMixin, DetailView):
+ template_name = "team_tasks.html"
+ context_object_name = 'team'
+ model = Team
+ slug_url_kwarg = 'team_slug'
+ active_menu = 'tasks'
+
+
+class TaskDetailView(CampViewMixin, TeamViewMixin, DetailView):
template_name = "task_detail.html"
context_object_name = "task"
model = TeamTask
+ active_menu = 'tasks'
-class TaskCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, CreateView):
+class TaskForm(forms.ModelForm):
+ class Meta:
+ model = TeamTask
+ fields = ['name', 'description', 'when', 'completed']
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.fields['when'].widget.widgets = [
+ forms.DateTimeInput(
+ attrs={"placeholder": "Start"}
+ ),
+ forms.DateTimeInput(
+ attrs={"placeholder": "End"}
+ )
+ ]
+
+
+class TaskCreateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, CreateView):
model = TeamTask
template_name = "task_form.html"
- fields = ['name', 'description', 'when', 'completed']
-
- 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', 'when', 'completed']
+ form_class = TaskForm
+ active_menu = 'tasks'
+
+ def get_team(self):
+ return Team.objects.get(
+ camp__slug=self.kwargs['camp_slug'],
+ slug=self.kwargs['team_slug']
+ )
+
+ 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, TeamViewMixin, EnsureTeamResponsibleMixin, UpdateView):
+ model = TeamTask
+ template_name = "task_form.html"
+ form_class = TaskForm
+ active_menu = 'tasks'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(**kwargs)
diff --git a/src/templates/base.html b/src/templates/base.html
index 4766b709..e3b2c5eb 100644
--- a/src/templates/base.html
+++ b/src/templates/base.html
@@ -58,7 +58,7 @@
{% endif %}