Conditioned behavior of views for concluded nomcoms. Fixes #1856.

- Legacy-Id: 10521
This commit is contained in:
Robert Sparks 2015-11-28 21:51:37 +00:00
parent e81b473282
commit 5bafd3d8fe
18 changed files with 434 additions and 153 deletions

View file

@ -0,0 +1,8 @@
import factory
from ietf.dbtemplate.models import DBTemplate
class DBTemplateFactory(factory.DjangoModelFactory):
class Meta:
model = DBTemplate

View file

@ -0,0 +1,40 @@
{% extends "ietf.html" %}
{% load bootstrap3 %}
{% block content %}
<h1>Template: {{ template }}</h1>
<h2>Meta information</h2>
<dl>
<dt>Title</dt>
<dd>{{ template.title }}</dt>
<dt>Group</dt>
<dd>{{ template.group }}</dd>
<dt>Template type</dt>
<dd>{{ template.type.name }}
{% if template.type.slug == "rst" %}
<p class="help-block">This template uses the syntax of reStructuredText. Get a quick reference at <a href="http://docutils.sourceforge.net/docs/user/rst/quickref.html">http://docutils.sourceforge.net/docs/user/rst/quickref.html</a>.</p>
<p class="help-block">You can do variable interpolation with $varialbe if the template allows any variable.</p>
{% endif %}
{% if template.type.slug == "django" %}
<p class="help-block">This template uses the syntax of the default django template framework. Get more info at <a href="https://docs.djangoproject.com/en/dev/topics/templates/">https://docs.djangoproject.com/en/dev/topics/templates/</a>.</p>
<p class="help-block">You can do variable interpolation with the current django markup &#123;&#123;variable&#125;&#125; if the template allows any variable.</p>
{% endif %}
{% if template.type.slug == "plain" %}
<p class="help-block">This template uses plain text, so no markup is used. You can do variable interpolation with $variable if the template allows any variable.</p>
{% endif %}
</dd>
{% if template.variables %}
<dt>Variables allowed in this template</dt>
<dd>{{ template.variables|linebreaks }}</dd>
{% endif %}
</dl>
<h2>Template content</h2>
<div class = "panel panel-default">
<p class='pasted'>{{ template.content }}</p>
</div>
{% endblock content %}

View file

@ -43,3 +43,19 @@ def template_edit(request, acronym, template_id, base_template='dbtemplate/templ
}
context.update(extra_context)
return render(request, base_template, context)
def template_show(request, acronym, template_id, base_template='dbtemplate/template_edit.html', extra_context=None):
group = get_object_or_404(Group, acronym=acronym)
chairs = group.role_set.filter(name__slug='chair')
extra_context = extra_context or {}
if not has_role(request.user, "Secretariat") and not chairs.filter(person__user=request.user).count():
return HttpResponseForbidden("You are not authorized to access this view")
template = get_object_or_404(DBTemplate, id=template_id, group=group)
context = {'template': template,
'group': group,
}
context.update(extra_context)
return render(request, base_template, context)

View file

@ -58,6 +58,11 @@ Tdb0MiLc+r/zvx8oXtgDjDUa
-----END PRIVATE KEY-----
'''
def provide_private_key_to_test_client(testcase):
session = testcase.client.session
session['NOMCOM_PRIVATE_KEY_%s'%testcase.nc.year()] = key
session.save()
def nomcom_kwargs_for_year(year=None, *args, **kwargs):
if not year:
year = random.randint(1980,2100)

View file

@ -27,11 +27,12 @@ from ietf.nomcom.models import NomineePosition, Position, Nominee, \
NomineePositionStateName, Feedback, FeedbackTypeName, \
Nomination
from ietf.nomcom.forms import EditMembersForm, EditMembersFormPreview
from ietf.nomcom.utils import get_nomcom_by_year, get_or_create_nominee
from ietf.nomcom.utils import get_nomcom_by_year, get_or_create_nominee, get_hash_nominee_position
from ietf.nomcom.management.commands.send_reminders import Command, is_time_to_send
from ietf.nomcom.factories import NomComFactory, nomcom_kwargs_for_year
from ietf.nomcom.factories import NomComFactory, nomcom_kwargs_for_year, provide_private_key_to_test_client
from ietf.person.factories import PersonFactory
from ietf.dbtemplate.factories import DBTemplateFactory
client_test_cert_files = None
@ -928,11 +929,13 @@ class InactiveNomcomTests(TestCase):
def setUp(self):
self.nc = NomComFactory.create(**nomcom_kwargs_for_year(group__state_id='conclude'))
self.plain_person = PersonFactory.create()
self.chair = self.nc.group.role_set.filter(name='chair').first().person
self.member = self.nc.group.role_set.filter(name='member').first().person
def test_feedback_closed(self):
for view in ['nomcom_public_feedback', 'nomcom_private_feedback']:
url = reverse(view, kwargs={'year': self.nc.year()})
who = self.plain_person if 'public' in view else self.nc.group.role_set.filter(name='member').first().person
who = self.plain_person if 'public' in view else self.member
login_testing_unauthorized(self, who.user.username, url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
@ -963,11 +966,151 @@ class InactiveNomcomTests(TestCase):
def test_nominations_closed(self):
for view in ['nomcom_public_nominate', 'nomcom_private_nominate']:
url = reverse(view, kwargs={'year': self.nc.year() })
who = self.plain_person if 'public' in view else self.nc.group.role_set.filter(name='member').first().person
who = self.plain_person if 'public' in view else self.member
login_testing_unauthorized(self, who.user.username, url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue( '(Concluded)' in q('h1').text())
self.assertTrue( 'closed' in q('.alert-warning').text())
def test_acceptance_closed(self):
today = datetime.date.today().strftime('%Y%m%d')
pid = self.nc.position_set.first().nomineeposition_set.first().id
url = reverse('nomcom_process_nomination_status', kwargs = {
'year' : self.nc.year(),
'nominee_position_id' : pid,
'state' : 'accepted',
'date' : today,
'hash' : get_hash_nominee_position(today,pid),
})
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
def test_can_view_but_cannot_edit_nomcom_settings(self):
url = reverse('nomcom_edit_nomcom',kwargs={'year':self.nc.year() })
login_testing_unauthorized(self, self.chair.user.username, url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.client.post(url,{})
self.assertEqual(response.status_code, 403)
def test_cannot_classify_feedback(self):
url = reverse('nomcom_view_feedback_pending',kwargs={'year':self.nc.year() })
login_testing_unauthorized(self, self.chair.user.username, url)
provide_private_key_to_test_client(self)
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
response = self.client.post(url,{})
self.assertEqual(response.status_code, 403)
def test_cannot_modify_nominees(self):
url = reverse('nomcom_private_index', kwargs={'year':self.nc.year()})
login_testing_unauthorized(self, self.chair.user.username, url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertFalse( q('#batch-action-form'))
test_data = {"action": "set_as_pending",
"selected": [1]}
response = self.client.post(url, test_data)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue('not active' in q('.alert-warning').text() )
def test_email_pasting_closed(self):
url = reverse('nomcom_private_feedback_email', kwargs={'year':self.nc.year()})
login_testing_unauthorized(self, self.chair.user.username, url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertFalse( q('#paste-email-feedback-form'))
test_data = {"email_text": "some garbage text",
}
response = self.client.post(url, test_data)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue('not active' in q('.alert-warning').text() )
def test_questionnaire_entry_closed(self):
url = reverse('nomcom_private_questionnaire', kwargs={'year':self.nc.year()})
login_testing_unauthorized(self, self.chair.user.username, url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertFalse( q('#questionnaireform'))
response = self.client.post(url, {})
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue('not active' in q('.alert-warning').text() )
def _test_send_reminders_closed(self,rtype):
url = reverse('nomcom_send_reminder_mail', kwargs={'year':self.nc.year(),'type':rtype })
login_testing_unauthorized(self, self.chair.user.username, url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertFalse( q('#reminderform'))
response = self.client.post(url, {})
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue('not active' in q('.alert-warning').text() )
def test_send_accept_reminders_closed(self):
self._test_send_reminders_closed('accept')
def test_send_questionnaire_reminders_closed(self):
self._test_send_reminders_closed('questionnaire')
def test_merge_closed(self):
url = reverse('nomcom_private_merge', kwargs={'year':self.nc.year()})
login_testing_unauthorized(self, self.chair.user.username, url)
response = self.client.get(url)
q = PyQuery(response.content)
self.assertFalse( q('#mergeform'))
response = self.client.post(url, {})
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertTrue('not active' in q('.alert-warning').text() )
def test_cannot_edit_position(self):
url = reverse('nomcom_edit_position',kwargs={'year':self.nc.year(),'position_id':self.nc.position_set.first().id})
login_testing_unauthorized(self, self.chair.user.username, url)
provide_private_key_to_test_client(self)
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
response = self.client.post(url,{})
self.assertEqual(response.status_code, 403)
def test_cannot_add_position(self):
url = reverse('nomcom_add_position',kwargs={'year':self.nc.year()})
login_testing_unauthorized(self, self.chair.user.username, url)
provide_private_key_to_test_client(self)
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
response = self.client.post(url,{})
self.assertEqual(response.status_code, 403)
def test_cannot_delete_position(self):
url = reverse('nomcom_remove_position',kwargs={'year':self.nc.year(),'position_id':self.nc.position_set.first().id})
login_testing_unauthorized(self, self.chair.user.username, url)
provide_private_key_to_test_client(self)
response = self.client.get(url)
self.assertEqual(response.status_code, 403)
response = self.client.post(url,{})
self.assertEqual(response.status_code, 403)
def test_can_view_but_not_edit_templates(self):
template = DBTemplateFactory.create(group=self.nc.group,
title='Test template',
path='/nomcom/'+self.nc.group.acronym+'/test',
variables='',
type_id='text',
content='test content')
url = reverse('nomcom_edit_template',kwargs={'year':self.nc.year(), 'template_id':template.id})
login_testing_unauthorized(self, self.chair.user.username, url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
q = PyQuery(response.content)
self.assertFalse( q('#templateform') )

View file

@ -1,5 +1,4 @@
from django.conf.urls import patterns, url
from django.views.generic import TemplateView
from ietf.nomcom.forms import EditMembersForm, EditMembersFormPreview
@ -22,8 +21,6 @@ urlpatterns = patterns('ietf.nomcom.views',
url(r'^(?P<year>\d{4})/private/send-reminder-mail/(?P<type>\w+)/$', 'send_reminder_mail', name='nomcom_send_reminder_mail'),
url(r'^(?P<year>\d{4})/private/edit-members/$', EditMembersFormPreview(EditMembersForm), name='nomcom_edit_members'),
url(r'^(?P<year>\d{4})/private/edit-nomcom/$', 'edit_nomcom', name='nomcom_edit_nomcom'),
url(r'^(?P<year>\d{4})/private/delete-nomcom/$', 'delete_nomcom', name='nomcom_delete_nomcom'),
url(r'^deleted/$', TemplateView.as_view(template_name='nomcom/deleted.html'), name='nomcom_deleted'),
url(r'^(?P<year>\d{4})/private/chair/templates/$', 'list_templates', name='nomcom_list_templates'),
url(r'^(?P<year>\d{4})/private/chair/templates/(?P<template_id>\d+)/$', 'edit_template', name='nomcom_edit_template'),
url(r'^(?P<year>\d{4})/private/chair/position/$', 'list_positions', name='nomcom_list_positions'),

View file

@ -15,7 +15,7 @@ from django.forms.models import modelformset_factory, inlineformset_factory
from ietf.dbtemplate.models import DBTemplate
from ietf.dbtemplate.views import template_edit
from ietf.dbtemplate.views import template_edit, template_show
from ietf.name.models import NomineePositionStateName, FeedbackTypeName
from ietf.group.models import Group, GroupEvent
from ietf.message.models import Message
@ -32,6 +32,8 @@ from ietf.nomcom.utils import (get_nomcom_by_year, store_nomcom_private_key,
HOME_TEMPLATE, NOMINEE_ACCEPT_REMINDER_TEMPLATE,NOMINEE_QUESTIONNAIRE_REMINDER_TEMPLATE)
from ietf.ietfauth.utils import role_required
import debug # pyflakes:ignore
def index(request):
nomcom_list = Group.objects.filter(type__slug='nomcom').order_by('acronym')
for nomcom in nomcom_list:
@ -137,21 +139,24 @@ def private_index(request, year):
is_chair = nomcom.group.has_role(request.user, "chair")
message = None
if is_chair and request.method == 'POST':
action = request.POST.get('action')
nominations_to_modify = request.POST.getlist('selected')
if nominations_to_modify:
nominations = all_nominee_positions.filter(id__in=nominations_to_modify)
if action == "set_as_accepted":
nominations.update(state='accepted')
message = ('success', 'The selected nominations have been set as accepted')
elif action == "set_as_declined":
nominations.update(state='declined')
message = ('success', 'The selected nominations have been set as declined')
elif action == "set_as_pending":
nominations.update(state='pending')
message = ('success', 'The selected nominations have been set as pending')
if nomcom.group.state_id != 'active':
message = ('warning', "This nomcom is not active. Request administrative assistance if Nominee state needs to change.")
else:
message = ('warning', "Please, select some nominations to work with")
action = request.POST.get('action')
nominations_to_modify = request.POST.getlist('selected')
if nominations_to_modify:
nominations = all_nominee_positions.filter(id__in=nominations_to_modify)
if action == "set_as_accepted":
nominations.update(state='accepted')
message = ('success', 'The selected nominations have been set as accepted')
elif action == "set_as_declined":
nominations.update(state='declined')
message = ('success', 'The selected nominations have been set as declined')
elif action == "set_as_pending":
nominations.update(state='pending')
message = ('success', 'The selected nominations have been set as pending')
else:
message = ('warning', "Please, select some nominations to work with")
filters = {}
questionnaire_state = "questionnaire"
@ -201,6 +206,14 @@ def send_reminder_mail(request, year, type):
nomcom = get_nomcom_by_year(year)
nomcom_template_path = '/nomcom/%s/' % nomcom.group.acronym
has_publickey = nomcom.public_key and True or False
if not has_publickey:
message = ('warning', "This Nomcom does not yet have a public key.")
elif nomcom.group.state_id != 'active':
message = ('warning', "This Nomcom is not active.")
else:
message = None
if type=='accept':
interesting_state = 'pending'
mail_path = nomcom_template_path + NOMINEE_ACCEPT_REMINDER_TEMPLATE
@ -228,9 +241,8 @@ def send_reminder_mail(request, year, type):
mail_template = DBTemplate.objects.filter(group=nomcom.group, path=mail_path)
mail_template = mail_template and mail_template[0] or None
message = None
if request.method == 'POST':
if request.method == 'POST' and not message:
selected_nominees = request.POST.getlist('selected')
selected_nominees = nominees.filter(id__in=selected_nominees)
if selected_nominees:
@ -241,6 +253,7 @@ def send_reminder_mail(request, year, type):
message = ('warning', 'No messages were sent.')
else:
message = ('warning', "Please, select at least one nominee")
return render_to_response('nomcom/send_reminder_mail.html',
{'nomcom': nomcom,
'year': year,
@ -257,14 +270,18 @@ def send_reminder_mail(request, year, type):
@role_required("Nomcom Chair", "Nomcom Advisor")
def private_merge(request, year):
nomcom = get_nomcom_by_year(year)
message = None
if request.method == 'POST':
form = MergeForm(request.POST, nomcom=nomcom)
if form.is_valid():
form.save()
message = ('success', 'The emails have been unified')
if nomcom.group.state_id != 'active':
message = ('warning', "This Nomcom is not active.")
form = None
else:
form = MergeForm(nomcom=nomcom)
message = None
if request.method == 'POST':
form = MergeForm(request.POST, nomcom=nomcom)
if form.is_valid():
form.save()
message = ('success', 'The emails have been unified')
else:
form = MergeForm(nomcom=nomcom)
return render_to_response('nomcom/private_merge.html',
{'nomcom': nomcom,
@ -422,14 +439,20 @@ def private_feedback_email(request, year):
template = 'nomcom/private_feedback_email.html'
if not has_publickey:
message = ('warning', "This Nomcom is not yet accepting feedback email")
return render_to_response(template,
{'message': message,
'nomcom': nomcom,
'year': year,
'selected': 'feedback_email',
'is_chair_task' : True,
}, RequestContext(request))
message = ('warning', "This Nomcom is not yet accepting feedback email.")
elif nomcom.group.state_id != 'active':
message = ('warning', "This Nomcom is not active, and is not accepting feedback email.")
else:
pass
if message:
return render_to_response(template,
{'message': message,
'nomcom': nomcom,
'year': year,
'selected': 'feedback_email',
'is_chair_task' : True,
}, RequestContext(request))
form = FeedbackEmailForm(nomcom=nomcom)
@ -458,14 +481,20 @@ def private_questionnaire(request, year):
template = 'nomcom/private_questionnaire.html'
if not has_publickey:
message = ('warning', "This Nomcom is not yet accepting questionnaires")
return render_to_response(template,
{'message': message,
'nomcom': nomcom,
'year': year,
'selected': 'questionnaire',
'is_chair_task' : True,
}, RequestContext(request))
message = ('warning', "This Nomcom is not yet accepting questionnaires.")
elif nomcom.group.state_id != 'active':
message = ('warning', "This Nomcom is not active, and is not accepting questionnaires.")
else:
pass
if message:
return render_to_response(template,
{'message': message,
'nomcom': nomcom,
'year': year,
'selected': 'questionnaire',
'is_chair_task' : True,
}, RequestContext(request))
if request.method == 'POST':
form = QuestionnaireForm(data=request.POST,
@ -499,6 +528,8 @@ def process_nomination_status(request, year, nominee_position_id, state, date, h
need_confirmation = True
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id == 'conclude':
return HttpResponseForbidden("This nomcom is concluded.")
nominee_position = get_object_or_404(NomineePosition, id=nominee_position_id)
if nominee_position.state.slug != "pending":
return HttpResponseForbidden("The nomination already was %s" % nominee_position.state)
@ -558,6 +589,8 @@ def view_feedback(request, year):
@nomcom_private_key_required
def view_feedback_pending(request, year):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id == 'conclude':
return HttpResponseForbidden("This nomcom is concluded.")
extra_ids = None
message = None
for message in messages.get_messages(request):
@ -741,6 +774,10 @@ def edit_nomcom(request, year):
model=ReminderDates,
form=ReminderDatesForm)
if request.method == 'POST':
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
formset = ReminderDateInlineFormSet(request.POST, instance=nomcom)
form = EditNomcomForm(request.POST,
request.FILES,
@ -765,22 +802,6 @@ def edit_nomcom(request, year):
}, RequestContext(request))
@role_required("Nomcom Chair", "Nomcom Advisor")
def delete_nomcom(request, year):
nomcom = get_nomcom_by_year(year)
if request.method == 'POST':
nomcom.delete()
messages.success(request, "Deleted NomCom data")
return redirect('nomcom_deleted')
return render(request, 'nomcom/delete_nomcom.html', {
'year': year,
'selected': 'edit_nomcom',
'nomcom': nomcom,
'is_chair_task' : True,
})
@role_required("Nomcom Chair", "Nomcom Advisor")
def list_templates(request, year):
@ -803,14 +824,23 @@ def edit_template(request, year, template_id):
nomcom = get_nomcom_by_year(year)
return_url = request.META.get('HTTP_REFERER', None)
return template_edit(request, nomcom.group.acronym, template_id,
base_template='nomcom/edit_template.html',
formclass=NomComTemplateForm,
extra_context={'year': year,
'return_url': return_url,
'nomcom': nomcom,
'is_chair_task' : True,
})
if nomcom.group.state_id=='conclude':
return template_show(request, nomcom.group.acronym, template_id,
base_template='nomcom/show_template.html',
extra_context={'year': year,
'return_url': return_url,
'nomcom': nomcom,
'is_chair_task' : True,
})
else:
return template_edit(request, nomcom.group.acronym, template_id,
base_template='nomcom/edit_template.html',
formclass=NomComTemplateForm,
extra_context={'year': year,
'return_url': return_url,
'nomcom': nomcom,
'is_chair_task' : True,
})
@role_required("Nomcom Chair", "Nomcom Advisor")
@ -830,6 +860,8 @@ def list_positions(request, year):
@role_required("Nomcom Chair", "Nomcom Advisor")
def remove_position(request, year, position_id):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
try:
position = nomcom.position_set.get(id=position_id)
except Position.DoesNotExist:
@ -849,6 +881,10 @@ def remove_position(request, year, position_id):
@role_required("Nomcom Chair", "Nomcom Advisor")
def edit_position(request, year, position_id=None):
nomcom = get_nomcom_by_year(year)
if nomcom.group.state_id=='conclude':
return HttpResponseForbidden('This nomcom is closed.')
if position_id:
try:
position = nomcom.position_set.get(id=position_id)

View file

@ -1,13 +0,0 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% block title %}NomCom deleted{% endblock %}
{% block content %}
{% origin %}
<h1>NomCom deleted</h1>
<p class="alert alert-success">All data about the NomCom has been removed.</p>
{% endblock %}

View file

@ -37,12 +37,6 @@
{% endbuttons %}
</form>
<h2>Delete Nomcom</h2>
<p>
<a class="btn btn-danger" href="{% url "nomcom_delete_nomcom" year %}" class="deletelink">Delete NomCom</a>
</p>
{% endblock %}
{% block js %}

View file

@ -31,7 +31,7 @@
{% endif %}
</dl>
<form method="post">
<form id="templateform" method="post">
{% csrf_token %}
{% bootstrap_form form %}

View file

@ -8,7 +8,9 @@
{% origin %}
<h2>Positions in {{ nomcom.group }}</h2>
<a class="btn btn-default" href="{% url "nomcom_add_position" year %}">Add new position</a>
{% if nomcom.group.state_id == 'active' %}
<a class="btn btn-default" href="{% url "nomcom_add_position" year %}">Add new position</a>
{% endif %}
{% if positions %}
{% for position in positions %}
@ -26,11 +28,13 @@
<a href="{% url "nomcom_edit_template" year template.id %}">{{ template }}</a><br>
{% endfor %}
</dd>
{% if nomcom.group.state_id == 'active' %}
<dt>Actions</dt>
<dd>
<a class="btn btn-default" href="{% url "nomcom_edit_position" year position.id %}">Edit</a>
<a class="btn btn-default" href="{% url "nomcom_remove_position" year position.id %}">Remove</a>
</dd>
{% endif %}
</dl>
{% endfor %}
{% else %}

View file

@ -26,6 +26,7 @@
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Chair/Advisor Tasks <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
{% if nomcom.group.state_id == 'active' %}
<li role = "presentation" class = "dropdown-header">Feedback Management</li>
<li {% if selected == "feedback_pending" %}class="active"{% endif %}><a href="{% url "nomcom_view_feedback_pending" year %}">Classify pending feedback</a></li>
<li {% if selected == "feedback_email" %}class="active"{% endif %}><a href="{% url "nomcom_private_feedback_email" year %}">Enter email feedback</a></li>
@ -33,11 +34,14 @@
<li {% if selected == "send_accept_reminder" %}class="active"{% endif %}><a href="{% url "nomcom_send_reminder_mail" year "accept" %}">Send accept reminder</a></li>
<li {% if selected == "send_questionnaire_reminder" %}class="active"{% endif %}><a href="{% url "nomcom_send_reminder_mail" year "questionnaire" %}">Send questionnaire reminder</a></li>
<li {% if selected == "merge" %}class="active"{% endif %}><a href="{% url "nomcom_private_merge" year %}">Merge Email Addresses</a></li>
{% endif %}
<li role = "presentation" class = "dropdown-header">Nomcom Configuration</li>
<li {% if selected == "edit_nomcom" %}class="active"{% endif %}><a href="{% url "nomcom_edit_nomcom" year %}">Edit Settings</a></li>
<li {% if selected == "edit_templates" %}class="active"{% endif %}><a href="{% url "nomcom_list_templates" year %}">Edit Pages</a></li>
<li {% if selected == "edit_positions" %}class="active"{% endif %}><a href="{% url "nomcom_list_positions" year %}">Edit Positions</a></li>
{% if nomcom.group.state_id == 'active' %}
<li {% if selected == "edit_members" %}class="active"{% endif %}><a href="{% url "nomcom_edit_members" year %}">Edit Members</a></li>
{% endif %}
</ul>
</li>

View file

@ -12,10 +12,10 @@
<div class="alert alert-{{ message.0 }}">{{ message.1 }}</div>
{% endif %}
{% if nomcom|has_publickey %}
{% if form %}
{% bootstrap_messages %}
<form id="questionnnaireform" method="post">
<form id="paste-email-feedback-form" method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}

View file

@ -66,14 +66,14 @@
</form>
{% if is_chair %}
{% if is_chair and nomcom.group.state_id == 'active' %}
<form class="form-inline" id="batch-action-form" method="post">{% csrf_token %}
{% endif %}
<table class="table table-condensed table-striped">
<thead>
<tr>
{% if is_chair %}<th colspan="2"><span class="fa fa-check"></span></th>{% endif %}
{% if is_chair and nomcom.group.state_id == 'active' %}<th colspan="2"><span class="fa fa-check"></span></th>{% endif %}
<th>Nominee</th>
<th>Position</th>
<th>State</th>
@ -83,7 +83,7 @@
<tbody>
{% for np in nominee_positions %}
<tr>
{% if is_chair %}
{% if is_chair and nomcom.group.state_id == 'active' %}
<td><input class="batch-select" type="checkbox" value="{{ np.id }}" name="selected"></td>
<td class="edit"><a class="btn btn-default btn-xs" href="{% url "nomcom_edit_nominee" year np.nominee.id %}">Edit</a></td>
{% endif %}
@ -100,24 +100,25 @@
</table>
{% if is_chair %}
{% if message %}
<p class="alert alert-{{ message.0 }}">{{ message.1 }}</p>
{% endif %}
<div class="form-group">
<label>Action:</label>
<select class="form-control" name="action">
<option value="" selected="selected">---------</option>
<option value="set_as_accepted">Set as accepted</option>
<option value="set_as_pending">Set as pending</option>
<option value="set_as_declined">Set as declined</option>
</select>
</div>
{% if nomcom.group.state_id == 'active' %}
<div class="form-group">
<label>Action:</label>
<select class="form-control" name="action">
<option value="" selected="selected">---------</option>
<option value="set_as_accepted">Set as accepted</option>
<option value="set_as_pending">Set as pending</option>
<option value="set_as_declined">Set as declined</option>
</select>
</div>
<button class="btn btn-warning" type="submit" title="Run action">Apply</button>
<button class="btn btn-warning" type="submit" title="Run action">Apply</button>
</form>
</form>
{% endif %}
{% endif %}
{% endblock %}

View file

@ -32,13 +32,15 @@
{% bootstrap_messages %}
<form id="nominateform" method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% if form %}
<form id="mergeform" method="post">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<input class="btn btn-primary" type="submit" value="Save" name="save">
{% endbuttons %}
</form>
{% buttons %}
<input class="btn btn-primary" type="submit" value="Save" name="save">
{% endbuttons %}
</form>
{% endif %}
{% endblock %}

View file

@ -13,7 +13,7 @@
<p class="alert alert-{{ message.0 }}">{{ message.1 }}</p>
{% endif %}
{% if nomcom|has_publickey %}
{% if form %}
{% if questionnaire_response %}
<h2>Questionnaire response</h2>
{{ questionnaire_response }}

View file

@ -11,51 +11,54 @@
{% origin %}
<h2>Send remider to {{reminder_description}}</h2>
<p>The message that will be sent is as follows:</p>
<pre>{{ mail_template.content|wrap_text:80 }}</pre>
{% if nomcom.group.state_id == 'active' %}
<p>The message that will be sent is as follows:</p>
<pre>{{ mail_template.content|wrap_text:80 }}</pre>
{% if mail_template %}
<p>
<a class="btn btn-default" href="{% url "nomcom_edit_template" year mail_template.id %}">Edit the message</a>
</p>
{% if mail_template %}
<p>
<a class="btn btn-default" href="{% url "nomcom_edit_template" year mail_template.id %}">Edit the message</a>
</p>
{% endif %}
<p>These are the nominees that are in the '{{state_description}}' state for the listed positions. </p>
<p>The message that will be sent is shown below the list of nominees. </p>
{% endif %}
<p>These are the nominees that are in the '{{state_description}}' state for the listed positions. </p>
<p>The message that will be sent is shown below the list of nominees. </p>
{% bootstrap_messages %}
{% if message %}
<div class="alert alert-{{ message.0 }}">{{ message.1 }}</div>
{% endif %}
<form method="post">
{% csrf_token %}
<table class="table table-condensed table-striped">
<thead>
<tr>
<th><span class="fa fa-check"></span></th>
<th>Nominee</th>
<th>Positions</th>
</tr>
</thead>
<tbody>
{% for nominee in nominees %}
{% if nomcom.group.state_id == 'active' %}
<form id="reminderform " method="post">
{% csrf_token %}
<table class="table table-condensed table-striped">
<thead>
<tr>
<td>
<input class="batch-select" type="checkbox" value="{{ nominee.id }}" name="selected" checked="checked">
</td>
<td>{{ nominee }}</td>
<td>{{nominee.interesting_positions|join:", "}}</td>
<th><span class="fa fa-check"></span></th>
<th>Nominee</th>
<th>Positions</th>
</tr>
{% endfor %}
</tbody>
</table>
{% buttons %}
<input class="btn btn-primary" type="submit" name="submit" value="Submit request">
{% endbuttons %}
</form>
</thead>
<tbody>
{% for nominee in nominees %}
<tr>
<td>
<input class="batch-select" type="checkbox" value="{{ nominee.id }}" name="selected" checked="checked">
</td>
<td>{{ nominee }}</td>
<td>{{nominee.interesting_positions|join:", "}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% buttons %}
<input class="btn btn-primary" type="submit" name="submit" value="Submit request">
{% endbuttons %}
</form>
{% endif %}
{% endblock %}

View file

@ -0,0 +1,41 @@
{% extends "nomcom/nomcom_private_base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% block subtitle %} - Template: {{ template }}{% endblock %}
{% load bootstrap3 %}
{% block nomcom_content %}
{% origin %}
<h2>Template: {{ template }}</h2>
<dl>
<dt>Title</dt>
<dd>{{ template.title }}</dt>
<dt>Group</dt>
<dd>{{ template.group }}</dd>
<dt>Template type</dt>
<dd>{{ template.type.name }}:
{% if template.type.slug == "rst" %}
This template uses the syntax of reStructuredText. Get a quick reference at <a href="http://docutils.sourceforge.net/docs/user/rst/quickref.html">http://docutils.sourceforge.net/docs/user/rst/quickref.html</a>. You can do variable interpolation with $variable if the template allows any variable.
{% elif template.type.slug == "django" %}
This template uses the syntax of the default django template framework. Get more info at <a href="https://docs.djangoproject.com/en/dev/topics/templates/">https://docs.djangoproject.com/en/dev/topics/templates/</a>. You can do variable interpolation with the current django markup &#123;&#123;variable&#125;&#125; if the template allows any variable.
{% elif template.type.slug == "plain" %}
This template uses plain text, so no markup is used. You can do variable interpolation with $variable if the template allows any variable.
{% endif %}
</dd>
{% if template.variables %}
<dt>Variables allowed in this template</dt>
<dd>{{ template.variables|linebreaks }}</dd>
{% endif %}
</dl>
<div class = "panel panel-default">
<p class='pasted'>{{ template.content }}</p>
</div>
{% buttons %}
<a class="btn btn-default pull-right" href="{% if return_url %}{{ return_url }}{% else %}../{% endif %}">Back</a>
{% endbuttons %}
{% endblock nomcom_content %}