Teams detail page was starting to get crowded. This is the start of a mostly visual, but also structural, refactor.
This commit is contained in:
parent
cf9e9ebd5a
commit
c68015fe26
|
@ -48,7 +48,7 @@ a, a:active, a:focus {
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav li a {
|
#top-navbar > .nav li a {
|
||||||
padding: 30px 7px;
|
padding: 30px 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ class Team(CampRelatedModel):
|
||||||
return '{} ({})'.format(self.name, self.camp)
|
return '{} ({})'.format(self.name, self.camp)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse_lazy('teams:detail', kwargs={'camp_slug': self.camp.slug, 'team_slug': self.slug})
|
return reverse_lazy('teams:general', kwargs={'camp_slug': self.camp.slug, 'team_slug': self.slug})
|
||||||
|
|
||||||
def save(self, **kwargs):
|
def save(self, **kwargs):
|
||||||
# generate slug if needed
|
# generate slug if needed
|
||||||
|
@ -215,6 +215,7 @@ class Team(CampRelatedModel):
|
||||||
|
|
||||||
|
|
||||||
class TeamMember(CampRelatedModel):
|
class TeamMember(CampRelatedModel):
|
||||||
|
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
'auth.User',
|
'auth.User',
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
|
|
|
@ -13,6 +13,6 @@ Fix IRC permissions for NickServ user {{ request.user.profile.nickserv_username
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form }}
|
{{ form }}
|
||||||
<button class="btn btn-success" type="submit"><i class="fas fa-check"></i> Yes Please</button>
|
<button class="btn btn-success" type="submit"><i class="fas fa-check"></i> Yes Please</button>
|
||||||
<a href="{% url 'teams:detail' camp_slug=team.camp.slug team_slug=team.slug %}" class="btn btn-default" type="submit"><i class="fas fa-times"></i> Cancel</a>
|
<a href="{% url 'teams:general' camp_slug=team.camp.slug team_slug=team.slug %}" class="btn btn-default" type="submit"><i class="fas fa-times"></i> Cancel</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'team_base.html' %}
|
||||||
{% load commonmark %}
|
{% load commonmark %}
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ Create Info item
|
||||||
in "{{ form.instance.category.headline }}"
|
in "{{ form.instance.category.headline }}"
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block team_content %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4>
|
<h4>
|
||||||
|
@ -36,6 +36,6 @@ in "{{ form.instance.category.headline }}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-footer"><i>This info item belongs to the <a href="{% url 'teams:detail' team_slug=team.slug camp_slug=team.camp.slug %}">{{ team.name }} Team</a></i></div>
|
<div class="panel-footer"><i>This info item belongs to the <a href="{% url 'teams:general' team_slug=team.slug camp_slug=team.camp.slug %}">{{ team.name }} Team</a></i></div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'team_base.html' %}
|
||||||
{% load commonmark %}
|
{% load commonmark %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{{ task.name }}
|
{{ task.name }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block team_content %}
|
||||||
<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|untrustedcommonmark }}</div>
|
<div class="panel-body">{{ task.description|untrustedcommonmark }}</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>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'team_base.html' %}
|
||||||
{% load commonmark %}
|
{% load commonmark %}
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ Create Task
|
||||||
for {{ team.name }} Team
|
for {{ team.name }} Team
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block team_content %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4>
|
<h4>
|
||||||
|
@ -30,7 +30,7 @@ for {{ team.name }} Team
|
||||||
<button type="submit" class="btn btn-primary">{% if form.instance.id %}Save{% else %}Create{% endif %}</button>
|
<button type="submit" class="btn btn-primary">{% if form.instance.id %}Save{% else %}Create{% endif %}</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-footer"><i>This task belongs to the <a href="{% url 'teams:detail' team_slug=team.slug camp_slug=team.camp.slug %}">{{ team.name }} Team</a></i></div>
|
<div class="panel-footer"><i>This task belongs to the <a href="{% url 'teams:general' team_slug=team.slug camp_slug=team.camp.slug %}">{{ team.name }} Team</a></i></div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
69
src/teams/templates/team_base.html
Normal file
69
src/teams/templates/team_base.html
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% load teams_tags %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Team: {{ team.name }} | {{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>{{ team.name }} Team</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<ul class="nav nav-pills nav-stacked">
|
||||||
|
<li {% if view.template_name == "team_general.html" %}class="active"{% endif %}>
|
||||||
|
<a href="{% url "teams:general" camp_slug=team.camp.slug team_slug=team.slug %}">
|
||||||
|
General
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li {% if view.template_name == "team_tasks.html" %}class="active"{% endif %}>
|
||||||
|
<a href="{% url "teams:tasks" camp_slug=team.camp.slug team_slug=team.slug %}">
|
||||||
|
Tasks
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li {% if view.template_name == "team_members.html" %}class="active"{% endif %}>
|
||||||
|
<a href="{% url "teams:members" camp_slug=team.camp.slug team_slug=team.slug %}">
|
||||||
|
Members
|
||||||
|
{% if request.user in team.responsible_members.all and team.unapproved_members %}
|
||||||
|
<span class="label label-danger">Pending</span>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
|
||||||
|
{% if request.user in team.members.all %}
|
||||||
|
<p>Your membership status: <b>{% membershipstatus user team %}</b></p>
|
||||||
|
|
||||||
|
{% if request.user in team.responsible_members.all %}
|
||||||
|
<a href="{% url 'teams:manage' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fas fa-cog"></i> Manage Team</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{% if team.needs_members %}
|
||||||
|
<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"><i class="fas fa-plus"></i> Join Team</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-10">
|
||||||
|
|
||||||
|
{% block team_content %}{% endblock %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -1,189 +0,0 @@
|
||||||
{% extends 'base.html' %}
|
|
||||||
{% load commonmark %}
|
|
||||||
{% load bootstrap3 %}
|
|
||||||
{% load teams_tags %}
|
|
||||||
|
|
||||||
{% block title %}
|
|
||||||
Team: {{ team.name }} | {{ block.super }}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<div class="page-header">
|
|
||||||
<h1>{{ team.name }} Team Details</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h4>Description</h4>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
{{ team.description|untrustedcommonmark }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# Team communications #}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h4>Communication Channels</h4>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
{{ team.camp.title }} teams primarily use mailing lists and IRC to communicate. The <b>{{ team.name }} team</b> can be contacted in the following ways:</p>
|
|
||||||
|
|
||||||
<h5>Mailing List</h5>
|
|
||||||
{% if team.mailing_list and request.user in team.approved_members.all %}
|
|
||||||
<p>The {{ team.name }} Team mailinglist is <b>{{ team.mailing_list }}</b>{% 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.</p>
|
|
||||||
{% elif team.mailing_list and team.mailinglist_nonmember_posts %}
|
|
||||||
<p>The {{ team.name }} Team mailinglist is <b>{{ team.mailing_list }}</b>{% 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.</p>
|
|
||||||
{% else %}
|
|
||||||
<p>The {{ team.name }} Team does not have a public mailing list, but it can be contacted through our main email <a href="mailto:info@bornhack.dk">info@bornhack.dk</a>.
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h5>IRC Channel</h5>
|
|
||||||
{% if team.public_irc_channel_name %}
|
|
||||||
<p>The {{ team.name }} Team public IRC channel is <a href="irc://{{ IRCBOT_SERVER_HOSTNAME }}/{{ team.public_irc_channel_name }}">{{ team.public_irc_channel_name }} on {{ IRCBOT_SERVER_HOSTNAME }}</a>.
|
|
||||||
{% else %}
|
|
||||||
<p>The {{ team.name }} Team does not have a public IRC channel, but it can be reached through our main IRC channel <a href="irc://{{ IRCBOT_SERVER_HOSTNAME }}/{{ IRCBOT_PUBLIC_CHANNEL }}">{{ IRCBOT_PUBLIC_CHANNEL }} on {{ IRCBOT_SERVER_HOSTNAME }}</a>.</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if request.user in team.approved_members.all and team.private_irc_channel_name %}
|
|
||||||
<p>The {{ team.name }} Team private IRC channel is <a href="irc://{{ IRCBOT_SERVER_HOSTNAME }}/{{ team.private_irc_channel_name }}">{{ team.private_irc_channel_name }} on {{ IRCBOT_SERVER_HOSTNAME }}</a>.</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# Team tasks #}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h4>Tasks</h4>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<p>The {{ team.name }} Team is responsible for the following tasks</p>
|
|
||||||
<table class="table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Description</th>
|
|
||||||
<th>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for task in team.tasks.all %}
|
|
||||||
<tr>
|
|
||||||
<td><a href="{% url 'teams:task_detail' slug=task.slug camp_slug=camp.slug team_slug=team.slug %}">{{ task.name }}</a></td>
|
|
||||||
<td>{{ task.description }}</td>
|
|
||||||
<td>
|
|
||||||
<a href="{% url 'teams:task_detail' camp_slug=camp.slug team_slug=team.slug slug=task.slug %}" class="btn btn-primary btn-sm"><i class="fas fa-search"></i> Details</a>
|
|
||||||
{% if request.user in team.responsible_members.all %}
|
|
||||||
<a href="{% url 'teams:task_update' camp_slug=camp.slug team_slug=team.slug slug=task.slug %}" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i> Edit Task</a>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% if request.user in team.responsible_members.all %}
|
|
||||||
<a href="{% url 'teams:task_create' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fas fa-plus"></i> Create Task</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# Team members #}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h4>Members</h4>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<p>The following <b>{{ team.approved_members.count }}</b> people {% if team.unapproved_members.count %}(and {{ team.unapproved_members.count }} pending){% endif %} are members of the <b>{{ team.name }} Team</b>:</p>
|
|
||||||
<table class="table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Name
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Status
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for teammember in team.memberships.all %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{{ teammember.user.profile.get_public_credit_name }} {% if teammember.user == request.user %}(this is you!){% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
Team {% if teammember.responsible %}Responsible{% else %}Member{% endif %}
|
|
||||||
{% if not teammember.approved %}(pending approval){% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>Your membership status: <b>{% membershipstatus user team %}</b></p>
|
|
||||||
|
|
||||||
{% if request.user in team.members.all %}
|
|
||||||
{% if team.irc_channel and team.irc_channel_managed and request.user.profile.nickserv_username %}
|
|
||||||
<a href="{% url 'teams:fix_irc_acl' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fas fa-wrench"></i> Fix IRC ACL</a>
|
|
||||||
{% endif %}
|
|
||||||
<a href="{% url 'teams:leave' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-danger"><i class="fas fa-times"></i> Leave Team</a>
|
|
||||||
{% else %}
|
|
||||||
{% if team.needs_members %}
|
|
||||||
<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"><i class="fas fa-plus"></i> Join Team</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if request.user in team.responsible_members.all %}
|
|
||||||
<a href="{% url 'teams:manage' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fas fa-cog"></i> Manage Team</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{# Team info categories section - only visible for team responsible #}
|
|
||||||
{% if request.user in team.responsible_members.all and team.info_categories.exists %}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h4>Info Categories</h4>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
|
|
||||||
{% for info_category in team.info_categories.all %}
|
|
||||||
|
|
||||||
<h4>{{ info_category.headline }}</h4>
|
|
||||||
<table class="table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Item name</th>
|
|
||||||
<th>Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for item in info_category.infoitems.all %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ item.headline }}</td>
|
|
||||||
<td>
|
|
||||||
<a href="{% url 'teams:info_item_update' camp_slug=camp.slug team_slug=team.slug category_anchor=info_category.anchor item_anchor=item.anchor %}"
|
|
||||||
class="btn btn-primary btn-sm">
|
|
||||||
<i class="fas fa-edit"></i> Edit
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<a href="{% url 'teams:info_item_create' camp_slug=camp.slug team_slug=team.slug category_anchor=info_category.anchor %}" class="btn btn-primary"><i class="fas fa-plus"></i> Create Info Item</a>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
48
src/teams/templates/team_general.html
Normal file
48
src/teams/templates/team_general.html
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{% extends 'team_base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% load teams_tags %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block team_content %}
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4>Description</h4>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{{ team.description|untrustedcommonmark }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# Team communications #}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4>Communication Channels</h4>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{{ team.camp.title }} teams primarily use mailing lists and IRC to communicate. The <b>{{ team.name }} team</b> can be contacted in the following ways:</p>
|
||||||
|
|
||||||
|
<h5>Mailing List</h5>
|
||||||
|
{% if team.mailing_list and request.user in team.approved_members.all %}
|
||||||
|
<p>The {{ team.name }} Team mailinglist is <b>{{ team.mailing_list }}</b>{% 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.</p>
|
||||||
|
{% elif team.mailing_list and team.mailinglist_nonmember_posts %}
|
||||||
|
<p>The {{ team.name }} Team mailinglist is <b>{{ team.mailing_list }}</b>{% 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.</p>
|
||||||
|
{% else %}
|
||||||
|
<p>The {{ team.name }} Team does not have a public mailing list, but it can be contacted through our main email <a href="mailto:info@bornhack.dk">info@bornhack.dk</a>.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h5>IRC Channel</h5>
|
||||||
|
{% if team.public_irc_channel_name %}
|
||||||
|
<p>The {{ team.name }} Team public IRC channel is <a href="irc://{{ IRCBOT_SERVER_HOSTNAME }}/{{ team.public_irc_channel_name }}">{{ team.public_irc_channel_name }} on {{ IRCBOT_SERVER_HOSTNAME }}</a>.
|
||||||
|
{% else %}
|
||||||
|
<p>The {{ team.name }} Team does not have a public IRC channel, but it can be reached through our main IRC channel <a href="irc://{{ IRCBOT_SERVER_HOSTNAME }}/{{ IRCBOT_PUBLIC_CHANNEL }}">{{ IRCBOT_PUBLIC_CHANNEL }} on {{ IRCBOT_SERVER_HOSTNAME }}</a>.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if request.user in team.approved_members.all and team.private_irc_channel_name %}
|
||||||
|
<p>The {{ team.name }} Team private IRC channel is <a href="irc://{{ IRCBOT_SERVER_HOSTNAME }}/{{ team.private_irc_channel_name }}">{{ team.private_irc_channel_name }} on {{ IRCBOT_SERVER_HOSTNAME }}</a>.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
52
src/teams/templates/team_info_categories.html
Normal file
52
src/teams/templates/team_info_categories.html
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
{% extends 'team_base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% load teams_tags %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block team_content %}
|
||||||
|
|
||||||
|
{% if request.user in team.responsible_members.all and team.info_categories.exists %}
|
||||||
|
<h4> SHOULD NOT HAPPEN !!! </h4>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4>Info Categories</h4>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
|
||||||
|
{% for info_category in team.info_categories.all %}
|
||||||
|
|
||||||
|
<h4>{{ info_category.headline }}</h4>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Item name</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for item in info_category.infoitems.all %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ item.headline }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'teams:info_item_update' camp_slug=camp.slug team_slug=team.slug category_anchor=info_category.anchor item_anchor=item.anchor %}"
|
||||||
|
class="btn btn-primary btn-sm">
|
||||||
|
<i class="fas fa-edit"></i> Edit
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<a href="{% url 'teams:info_item_create' camp_slug=camp.slug team_slug=team.slug category_anchor=info_category.anchor %}" class="btn btn-primary"><i class="fas fa-plus"></i> Create Info Item</a>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -1,11 +1,11 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'team_base.html' %}
|
||||||
{% load commonmark %}
|
{% load commonmark %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
Join Team: {{ team.name }} | {{ block.super }}
|
Join Team: {{ team.name }} | {{ block.super }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block team_content %}
|
||||||
|
|
||||||
<p class="lead">Really join the <b>{{ team.name }}</b> Team for <b>{{ team.camp.title }}</b>?</p>
|
<p class="lead">Really join the <b>{{ team.name }}</b> Team for <b>{{ team.camp.title }}</b>?</p>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'team_base.html' %}
|
||||||
{% load commonmark %}
|
{% load commonmark %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
Leave Team: {{ team.name }} | {{ block.super }}
|
Leave Team: {{ team.name }} | {{ block.super }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block team_content %}
|
||||||
|
|
||||||
<h3>Leave {{ team.name }} Team</h3>
|
<h3>Leave {{ team.name }} Team</h3>
|
||||||
<p class="lead">Really leave the <b>{{ team.name }}</b> team?<p>
|
<p class="lead">Really leave the <b>{{ team.name }}</b> team?<p>
|
||||||
|
|
|
@ -33,7 +33,9 @@ Teams | {{ block.super }}
|
||||||
{% for team in teams %}
|
{% for team in teams %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'teams:detail' camp_slug=camp.slug team_slug=team.slug %}">
|
{{ camp.slug}}
|
||||||
|
{{ team.slug}}
|
||||||
|
<a href="{% url 'teams:general' camp_slug=camp.slug team_slug=team.slug %}">
|
||||||
{{ team.name }} Team
|
{{ team.name }} Team
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -63,7 +65,7 @@ Teams | {{ block.super }}
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group-vertical">
|
<div class="btn-group-vertical">
|
||||||
<a class="btn btn-primary" href="{% url 'teams:detail' camp_slug=camp.slug team_slug=team.slug %}"><i class="fas fa-search"></i> Details</a>
|
<a class="btn btn-primary" href="{% url 'teams:general' camp_slug=camp.slug team_slug=team.slug %}"><i class="fas fa-search"></i> Details</a>
|
||||||
{% if request.user in team.responsible_members.all %}
|
{% if request.user in team.responsible_members.all %}
|
||||||
<a href="{% url 'teams:manage' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fas fa-cog"></i> Manage</a>
|
<a href="{% url 'teams:manage' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fas fa-cog"></i> Manage</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'team_base.html' %}
|
||||||
{% load commonmark %}
|
{% load commonmark %}
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
||||||
Manage Team: {{ team.name }} | {{ block.super }}
|
Manage Team: {{ team.name }} | {{ block.super }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block team_content %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><h4>Manage {{ team.name }} Team</h4></div>
|
<div class="panel-heading"><h4>Manage {{ team.name }} Team</h4></div>
|
||||||
<div class="panel-body" style="margin-left: 1em; margin-right: 1em;">
|
<div class="panel-body" style="margin-left: 1em; margin-right: 1em;">
|
||||||
|
@ -18,81 +18,12 @@ Manage Team: {{ team.name }} | {{ block.super }}
|
||||||
|
|
||||||
{% buttons %}
|
{% buttons %}
|
||||||
<button class="btn btn-success pull-right" type="submit"><i class="fas fa-check"></i> Save Team</button>
|
<button class="btn btn-success pull-right" type="submit"><i class="fas fa-check"></i> Save Team</button>
|
||||||
<a class="btn btn-primary pull-right" href="{% url 'teams:detail' team_slug=team.slug camp_slug=camp.slug %}"><i class="fas fa-times"></i> Cancel</a>
|
<a class="btn btn-primary pull-right" href="{% url 'teams:general' team_slug=team.slug camp_slug=camp.slug %}"><i class="fas fa-times"></i> Cancel</a>
|
||||||
{% endbuttons %}
|
{% endbuttons %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading"><h4>Manage {{ team.name }} Team Members</h4></div>
|
|
||||||
<div class="panel-body" style="margin-left: 1em; margin-right: 1em;">
|
|
||||||
{% if team.teammember_set.exists %}
|
|
||||||
<table class="table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Username
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Name
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Email
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Description
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Public Credit Name
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Membership
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Action
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for membership in team.teammember_set.all %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{{ membership.user }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ membership.user.profile.name }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ membership.user.profile.email }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ membership.user.profile.description }}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ 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 %}<span class="text-warning">(name not approved)</span>{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% if membership.approved %}member{% else %}pending{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="btn-group-vertical">
|
|
||||||
<a class="btn btn-danger" href="{% url 'teams:teammember_remove' camp_slug=camp.slug pk=membership.id %}"><i class="fas fa-trash-o"></i> Remove Member</a>
|
|
||||||
{% if not membership.approved %}
|
|
||||||
<a class="btn btn-success" href="{% url 'teams:teammember_approve' camp_slug=camp.slug pk=membership.id %}"><i class="fas fa-check"></i> Approve Member</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% else %}
|
|
||||||
<p>No members found!</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
84
src/teams/templates/team_members.html
Normal file
84
src/teams/templates/team_members.html
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
{% extends 'team_base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% load teams_tags %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block team_content %}
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4>Members</h4>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p>The following <b>{{ team.approved_members.count }}</b> people {% if team.unapproved_members.count %}(and {{ team.unapproved_members.count }} pending){% endif %} are members of the <b>{{ team.name }} Team</b>:</p>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Name
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Status
|
||||||
|
</th>
|
||||||
|
{% if request.user in team.responsible_members.all %}
|
||||||
|
<th>
|
||||||
|
Action
|
||||||
|
</th>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for teammember in team.memberships.all %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ teammember.user.profile.get_public_credit_name }} {% if teammember.user == request.user %}(this is you!){% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
Team {% if teammember.responsible %}Responsible{% else %}Member{% endif %}
|
||||||
|
{% if not teammember.approved %}(pending approval){% endif %}
|
||||||
|
</td>
|
||||||
|
{% if request.user in team.responsible_members.all %}
|
||||||
|
<td>
|
||||||
|
<div class="btn-group-vertical">
|
||||||
|
<a class="btn btn-danger"
|
||||||
|
href="{% url 'teams:teammember_remove' camp_slug=camp.slug team_slug=team.slug pk=teammember.id %}">
|
||||||
|
<i class="fas fa-trash-o"></i> Remove Member
|
||||||
|
</a>
|
||||||
|
{% if not teammember.approved %}
|
||||||
|
<a class="btn btn-success"
|
||||||
|
href="{% url 'teams:teammember_approve' camp_slug=camp.slug team_slug=team.slug pk=teammember.id %}">
|
||||||
|
<i class="fas fa-check"></i> Approve Member
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<p>No members found!</p>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% if request.user.authorized %}
|
||||||
|
|
||||||
|
<p>Your membership status: <b>{% membershipstatus user team %}</b></p>
|
||||||
|
|
||||||
|
{% if request.user in team.members.all %}
|
||||||
|
{% if team.irc_channel and team.irc_channel_managed and request.user.profile.nickserv_username %}
|
||||||
|
<a href="{% url 'teams:fix_irc_acl' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fas fa-wrench"></i> Fix IRC ACL</a>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{% url 'teams:leave' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-danger"><i class="fas fa-times"></i> Leave Team</a>
|
||||||
|
{% else %}
|
||||||
|
{% if team.needs_members %}
|
||||||
|
<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"><i class="fas fa-plus"></i> Join Team</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
42
src/teams/templates/team_tasks.html
Normal file
42
src/teams/templates/team_tasks.html
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{% extends 'team_base.html' %}
|
||||||
|
{% load commonmark %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% load teams_tags %}
|
||||||
|
|
||||||
|
{% block team_content %}
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4>Tasks</h4>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p>The {{ team.name }} Team is responsible for the following tasks</p>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for task in team.tasks.all %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{% url 'teams:task_detail' slug=task.slug camp_slug=camp.slug team_slug=team.slug %}">{{ task.name }}</a></td>
|
||||||
|
<td>{{ task.description }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'teams:task_detail' camp_slug=camp.slug team_slug=team.slug slug=task.slug %}" class="btn btn-primary btn-sm"><i class="fas fa-search"></i> Details</a>
|
||||||
|
{% if request.user in team.responsible_members.all %}
|
||||||
|
<a href="{% url 'teams:task_update' camp_slug=camp.slug team_slug=team.slug slug=task.slug %}" class="btn btn-primary btn-sm"><i class="fas fa-edit"></i> Edit Task</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% if request.user in team.responsible_members.all %}
|
||||||
|
<a href="{% url 'teams:task_create' camp_slug=camp.slug team_slug=team.slug %}" class="btn btn-primary"><i class="fas fa-plus"></i> Create Task</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -1,11 +1,11 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'team_base.html' %}
|
||||||
{% load commonmark %}
|
{% load commonmark %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
Approve team member {{ teammember.user.profile.name }} for the {{ teammember.team.name }} team
|
Approve team member {{ teammember.user.profile.name }} for the {{ teammember.team.name }} team
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block team_content %}
|
||||||
|
|
||||||
<h3>Approve member {{ teammember.user.profile.name }} for the {{ teammember.team.name }} team</h3>
|
<h3>Approve member {{ teammember.user.profile.name }} for the {{ teammember.team.name }} team</h3>
|
||||||
<p class="lead">Really approve the user <b>{{ teammember.user.profile.name }}</b> for the {{ teammember.team.name }} team? The user will receive an email with a message.<p>
|
<p class="lead">Really approve the user <b>{{ teammember.user.profile.name }}</b> for the {{ teammember.team.name }} team? The user will receive an email with a message.<p>
|
||||||
|
@ -13,6 +13,7 @@ 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="fas fa-check"></i> Add teammember</button>
|
<button class="btn btn-success" type="submit"><i class="fas fa-check"></i> Add teammember</button>
|
||||||
<a href="{% url 'teams:detail' camp_slug=teammember.team.camp.slug team_slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fas fa-times"></i> Cancel</a>
|
<a href="{% url 'teams:general' camp_slug=teammember.team.camp.slug team_slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fas fa-times"></i> Cancel</a>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'team_base.html' %}
|
||||||
{% load commonmark %}
|
{% load commonmark %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.name }} team
|
Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.name }} team
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block team_content %}
|
||||||
|
|
||||||
<h3>Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.name }} team</h3>
|
<h3>Remove member {{ teammember.user.profile.name }} from the {{ teammember.team.name }} team</h3>
|
||||||
<p class="lead">Really remove the user <b>{{ teammember.user.profile.name }}</b> from the {{ teammember.team.name }} team? The user will receive an email with a message.<p>
|
<p class="lead">Really remove the user <b>{{ teammember.user.profile.name }}</b> from the {{ teammember.team.name }} team? The user will receive an email with a message.<p>
|
||||||
|
@ -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="fas fa-trash-o"></i> Remove teammember</button>
|
<button class="btn btn-danger" type="submit"><i class="fas fa-trash-o"></i> Remove teammember</button>
|
||||||
<a href="{% url 'teams:detail' camp_slug=teammember.team.camp.slug team_slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fas fa-times"></i> Cancel</a>
|
<a href="{% url 'teams:general' camp_slug=teammember.team.camp.slug team_slug=teammember.team.slug %}" class="btn btn-default" type="submit"><i class="fas fa-times"></i> Cancel</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -2,17 +2,27 @@ from django.urls import path, include
|
||||||
|
|
||||||
from teams.views.base import (
|
from teams.views.base import (
|
||||||
TeamListView,
|
TeamListView,
|
||||||
TeamMemberRemoveView,
|
TeamGeneralView,
|
||||||
TeamMemberApproveView,
|
|
||||||
TeamDetailView,
|
|
||||||
TeamJoinView,
|
|
||||||
TeamLeaveView,
|
|
||||||
TeamManageView,
|
TeamManageView,
|
||||||
FixIrcAclView,
|
FixIrcAclView,
|
||||||
)
|
)
|
||||||
from teams.views.info import InfoItemUpdateView, InfoItemCreateView, InfoItemDeleteView
|
|
||||||
|
from teams.views.members import (
|
||||||
|
TeamMembersView,
|
||||||
|
TeamMemberRemoveView,
|
||||||
|
TeamMemberApproveView,
|
||||||
|
TeamJoinView,
|
||||||
|
TeamLeaveView,
|
||||||
|
)
|
||||||
|
|
||||||
|
from teams.views.info import (
|
||||||
|
InfoItemUpdateView,
|
||||||
|
InfoItemCreateView,
|
||||||
|
InfoItemDeleteView,
|
||||||
|
)
|
||||||
|
|
||||||
from teams.views.tasks import (
|
from teams.views.tasks import (
|
||||||
|
TeamTasksView,
|
||||||
TaskCreateView,
|
TaskCreateView,
|
||||||
TaskDetailView,
|
TaskDetailView,
|
||||||
TaskUpdateView,
|
TaskUpdateView,
|
||||||
|
@ -26,26 +36,12 @@ urlpatterns = [
|
||||||
TeamListView.as_view(),
|
TeamListView.as_view(),
|
||||||
name='list'
|
name='list'
|
||||||
),
|
),
|
||||||
path(
|
|
||||||
'members/', include([
|
|
||||||
path(
|
|
||||||
'<int:pk>/remove/',
|
|
||||||
TeamMemberRemoveView.as_view(),
|
|
||||||
name='teammember_remove',
|
|
||||||
),
|
|
||||||
path(
|
|
||||||
'<int:pk>/approve/',
|
|
||||||
TeamMemberApproveView.as_view(),
|
|
||||||
name='teammember_approve',
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
path(
|
path(
|
||||||
'<slug:team_slug>/', include([
|
'<slug:team_slug>/', include([
|
||||||
path(
|
path(
|
||||||
'',
|
'',
|
||||||
TeamDetailView.as_view(),
|
TeamGeneralView.as_view(),
|
||||||
name='detail'
|
name='general'
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
'join/',
|
'join/',
|
||||||
|
@ -67,8 +63,32 @@ urlpatterns = [
|
||||||
FixIrcAclView.as_view(),
|
FixIrcAclView.as_view(),
|
||||||
name='fix_irc_acl',
|
name='fix_irc_acl',
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
'members/', include([
|
||||||
|
path(
|
||||||
|
'',
|
||||||
|
TeamMembersView.as_view(),
|
||||||
|
name='members'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'<int:pk>/remove/',
|
||||||
|
TeamMemberRemoveView.as_view(),
|
||||||
|
name='teammember_remove',
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'<int:pk>/approve/',
|
||||||
|
TeamMemberApproveView.as_view(),
|
||||||
|
name='teammember_approve',
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
'tasks/', include([
|
'tasks/', include([
|
||||||
|
path(
|
||||||
|
'',
|
||||||
|
TeamTasksView.as_view(),
|
||||||
|
name='tasks',
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
'create/',
|
'create/',
|
||||||
TaskCreateView.as_view(),
|
TaskCreateView.as_view(),
|
||||||
|
|
|
@ -7,11 +7,8 @@ from django.contrib import messages
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from profiles.models import Profile
|
from .mixins import EnsureTeamResponsibleMixin
|
||||||
|
|
||||||
from .mixins import EnsureTeamResponsibleMixin, EnsureTeamMemberResponsibleMixin
|
|
||||||
from ..models import Team, TeamMember
|
from ..models import Team, TeamMember
|
||||||
from ..email import add_added_membership_email, add_removed_membership_email
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger("bornhack.%s" % __name__)
|
logger = logging.getLogger("bornhack.%s" % __name__)
|
||||||
|
@ -23,14 +20,14 @@ class TeamListView(CampViewMixin, ListView):
|
||||||
context_object_name = 'teams'
|
context_object_name = 'teams'
|
||||||
|
|
||||||
|
|
||||||
class TeamDetailView(CampViewMixin, DetailView):
|
class TeamGeneralView(CampViewMixin, DetailView):
|
||||||
template_name = "team_detail.html"
|
template_name = "team_general.html"
|
||||||
context_object_name = 'team'
|
context_object_name = 'team'
|
||||||
model = Team
|
model = Team
|
||||||
slug_url_kwarg = 'team_slug'
|
slug_url_kwarg = 'team_slug'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
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_SERVER_HOSTNAME'] = settings.IRCBOT_SERVER_HOSTNAME
|
||||||
context['IRCBOT_PUBLIC_CHANNEL'] = settings.IRCBOT_PUBLIC_CHANNEL
|
context['IRCBOT_PUBLIC_CHANNEL'] = settings.IRCBOT_PUBLIC_CHANNEL
|
||||||
return context
|
return context
|
||||||
|
@ -39,102 +36,20 @@ class TeamDetailView(CampViewMixin, DetailView):
|
||||||
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', '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'
|
slug_url_kwarg = 'team_slug'
|
||||||
|
|
||||||
def get_success_url(self):
|
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):
|
def form_valid(self, form):
|
||||||
messages.success(self.request, "Team has been saved")
|
messages.success(self.request, "Team has been saved")
|
||||||
return super().form_valid(form)
|
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):
|
class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
|
||||||
template_name = "fix_irc_acl.html"
|
template_name = "fix_irc_acl.html"
|
||||||
model = Team
|
model = Team
|
||||||
|
@ -151,17 +66,17 @@ class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
|
||||||
# check if the logged in user has an approved membership of this team
|
# check if the logged in user has an approved membership of this team
|
||||||
if request.user not in self.get_object().approved_members.all():
|
if request.user not in self.get_object().approved_members.all():
|
||||||
messages.error(request, 'No thanks')
|
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
|
# check if we manage the channel for this team
|
||||||
if not self.get_object().irc_channel or not self.get_object().irc_channel_managed:
|
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')
|
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
|
# check if user has a nickserv username
|
||||||
if not request.user.profile.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!')
|
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
|
return response
|
||||||
|
|
||||||
|
@ -177,7 +92,7 @@ class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
|
||||||
except TeamMember.DoesNotExist:
|
except TeamMember.DoesNotExist:
|
||||||
# this membership is already marked as membership.irc_channel_acl_ok=False, no need to do anything
|
# 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')
|
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(
|
return super().get(
|
||||||
request, *args, **kwargs
|
request, *args, **kwargs
|
||||||
|
@ -195,5 +110,5 @@ class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView):
|
||||||
membership.irc_channel_acl_ok = False
|
membership.irc_channel_acl_ok = False
|
||||||
membership.save()
|
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))
|
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)
|
||||||
|
|
||||||
|
|
117
src/teams/views/members.py
Normal file
117
src/teams/views/members.py
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
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
|
||||||
|
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'
|
||||||
|
|
||||||
|
|
||||||
|
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:general', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['team'] = self.get_object().team
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
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:general', camp_slug=self.camp.slug, team_slug=form.instance.team.slug)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['team'] = self.get_object().team
|
||||||
|
return context
|
|
@ -13,7 +13,7 @@ class EnsureTeamResponsibleMixin(object):
|
||||||
self.team = Team.objects.get(slug=kwargs['team_slug'], camp=self.camp)
|
self.team = Team.objects.get(slug=kwargs['team_slug'], camp=self.camp)
|
||||||
if request.user not in self.team.responsible_members.all():
|
if request.user not in self.team.responsible_members.all():
|
||||||
messages.error(request, 'No thanks')
|
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(
|
return super().dispatch(
|
||||||
request, *args, **kwargs
|
request, *args, **kwargs
|
||||||
|
@ -29,7 +29,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_members.all():
|
if request.user not in self.get_object().team.responsible_members.all():
|
||||||
messages.error(request, 'No thanks')
|
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(
|
return super().dispatch(
|
||||||
request, *args, **kwargs
|
request, *args, **kwargs
|
||||||
|
|
|
@ -3,15 +3,27 @@ from django.http import HttpResponseRedirect
|
||||||
from django.views.generic import DetailView, CreateView, UpdateView
|
from django.views.generic import DetailView, CreateView, UpdateView
|
||||||
|
|
||||||
from camps.mixins import CampViewMixin
|
from camps.mixins import CampViewMixin
|
||||||
from ..models import TeamTask
|
from ..models import Team, TeamTask
|
||||||
from .mixins import EnsureTeamResponsibleMixin
|
from .mixins import EnsureTeamResponsibleMixin
|
||||||
|
|
||||||
|
|
||||||
|
class TeamTasksView(CampViewMixin, DetailView):
|
||||||
|
template_name = "team_tasks.html"
|
||||||
|
context_object_name = 'team'
|
||||||
|
model = Team
|
||||||
|
slug_url_kwarg = 'team_slug'
|
||||||
|
|
||||||
|
|
||||||
class TaskDetailView(CampViewMixin, DetailView):
|
class TaskDetailView(CampViewMixin, DetailView):
|
||||||
template_name = "task_detail.html"
|
template_name = "task_detail.html"
|
||||||
context_object_name = "task"
|
context_object_name = "task"
|
||||||
model = TeamTask
|
model = TeamTask
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['team'] = self.object.team
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class TaskCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, CreateView):
|
class TaskCreateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMixin, CreateView):
|
||||||
model = TeamTask
|
model = TeamTask
|
||||||
|
@ -54,4 +66,4 @@ class TaskUpdateView(LoginRequiredMixin, CampViewMixin, EnsureTeamResponsibleMix
|
||||||
return HttpResponseRedirect(task.get_absolute_url())
|
return HttpResponseRedirect(task.get_absolute_url())
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return self.get_object().get_absolute_url()
|
return self.get_object().get_absolute_url()
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div id="navbar" class="navbar-collapse collapse">
|
<div id="top-navbar" class="navbar-collapse collapse">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li><a href="{% url 'news:index' %}">News</a></li>
|
<li><a href="{% url 'news:index' %}">News</a></li>
|
||||||
<li><a href="{% url 'shop:index' %}">Shop</a></li>
|
<li><a href="{% url 'shop:index' %}">Shop</a></li>
|
||||||
|
|
Loading…
Reference in a new issue