Add support for structured entry and storage of joint sessions in meetings.
- Also adds additional tests for the SessionForm
- Fixes a javascript error in session requests for non-WG groups,
that could cause incorrect form behaviour.
- Expands the tests added in [17289] a bit.
- Legacy-Id: 17321
Note: SVN reference [17289] has been migrated to Git commit a227813dc5
This commit is contained in:
parent
1bfcf2e699
commit
825a054d19
ietf
meeting
secr
sreq
static/secr/js
templates/includes
templates/meeting
|
@ -900,6 +900,7 @@ class Session(models.Model):
|
|||
short = models.CharField(blank=True, max_length=32, help_text="Short version of 'name' above, for use in filenames.")
|
||||
type = ForeignKey(TimeSlotTypeName)
|
||||
group = ForeignKey(Group) # The group type historically determined the session type. BOFs also need to be added as a group. Note that not all meeting requests have a natural group to associate with.
|
||||
joint_with_groups = models.ManyToManyField(Group, related_name='sessions_joint_in')
|
||||
attendees = models.IntegerField(null=True, blank=True)
|
||||
agenda_note = models.CharField(blank=True, max_length=255)
|
||||
requested_duration = models.DurationField(default=datetime.timedelta(0))
|
||||
|
@ -1023,6 +1024,9 @@ class Session(models.Model):
|
|||
|
||||
def is_material_submission_cutoff(self):
|
||||
return datetime.date.today() > self.meeting.get_submission_correction_date()
|
||||
|
||||
def joint_with_groups_acronyms(self):
|
||||
return [group.acronym for group in self.joint_with_groups.all()]
|
||||
|
||||
def __str__(self):
|
||||
if self.meeting.type_id == "interim":
|
||||
|
|
|
@ -22,6 +22,7 @@ NUM_SESSION_CHOICES = (('','--Please select'),('1','1'),('2','2'))
|
|||
# LENGTH_SESSION_CHOICES = (('','--Please select'),('1800','30 minutes'),('3600','1 hour'),('5400','1.5 hours'), ('7200','2 hours'),('9000','2.5 hours'))
|
||||
LENGTH_SESSION_CHOICES = (('','--Please select'),('1800','30 minutes'),('3600','1 hour'),('5400','1.5 hours'), ('7200','2 hours'))
|
||||
SESSION_TIME_RELATION_CHOICES = (('', 'No preference'),) + Constraint.TIME_RELATION_CHOICES
|
||||
JOINT_FOR_SESSION_CHOICES = (('1', 'First session'), ('2', 'Second session'), ('3', 'Third session'), )
|
||||
|
||||
# -------------------------------------------------
|
||||
# Helper Functions
|
||||
|
@ -86,10 +87,13 @@ class SessionForm(forms.Form):
|
|||
conflict1 = forms.CharField(max_length=255,required=False)
|
||||
conflict2 = forms.CharField(max_length=255,required=False)
|
||||
conflict3 = forms.CharField(max_length=255,required=False)
|
||||
joint_with_groups = forms.CharField(max_length=255,required=False)
|
||||
joint_for_session = forms.ChoiceField(choices=JOINT_FOR_SESSION_CHOICES, required=False)
|
||||
comments = forms.CharField(max_length=200,required=False)
|
||||
wg_selector1 = forms.ChoiceField(choices=[],required=False)
|
||||
wg_selector2 = forms.ChoiceField(choices=[],required=False)
|
||||
wg_selector3 = forms.ChoiceField(choices=[],required=False)
|
||||
wg_selector4 = forms.ChoiceField(choices=[],required=False)
|
||||
third_session = forms.BooleanField(required=False)
|
||||
resources = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,required=False)
|
||||
bethere = SearchablePersonsField(label="Must be present", required=False)
|
||||
|
@ -115,7 +119,7 @@ class SessionForm(forms.Form):
|
|||
other_groups = list(allowed_conflicting_groups().exclude(pk=group.pk).values_list('acronym', 'acronym').order_by('acronym'))
|
||||
self.fields['adjacent_with_wg'].choices = [('', '--No preference')] + other_groups
|
||||
group_acronym_choices = [('','--Select WG(s)')] + other_groups
|
||||
for i in range(1, 4):
|
||||
for i in range(1, 5):
|
||||
self.fields['wg_selector{}'.format(i)].choices = group_acronym_choices
|
||||
|
||||
# disabling handleconflictfield (which only enables or disables form elements) while we're hacking the meaning of the three constraints currently in use:
|
||||
|
@ -125,6 +129,7 @@ class SessionForm(forms.Form):
|
|||
self.fields['wg_selector1'].widget.attrs['onChange'] = "document.form_post.conflict1.value=document.form_post.conflict1.value + ' ' + this.options[this.selectedIndex].value; return 1;"
|
||||
self.fields['wg_selector2'].widget.attrs['onChange'] = "document.form_post.conflict2.value=document.form_post.conflict2.value + ' ' + this.options[this.selectedIndex].value; return 1;"
|
||||
self.fields['wg_selector3'].widget.attrs['onChange'] = "document.form_post.conflict3.value=document.form_post.conflict3.value + ' ' + this.options[this.selectedIndex].value; return 1;"
|
||||
self.fields['wg_selector4'].widget.attrs['onChange'] = "document.form_post.joint_with_groups.value=document.form_post.joint_with_groups.value + ' ' + this.options[this.selectedIndex].value; return 1;"
|
||||
|
||||
# disabling check_prior_conflict javascript while we're hacking the meaning of the three constraints currently in use
|
||||
#self.fields['wg_selector2'].widget.attrs['onClick'] = "return check_prior_conflict(2);"
|
||||
|
@ -159,7 +164,12 @@ class SessionForm(forms.Form):
|
|||
conflict = self.cleaned_data['conflict3']
|
||||
check_conflict(conflict, self.group)
|
||||
return conflict
|
||||
|
||||
|
||||
def clean_joint_with_groups(self):
|
||||
groups = self.cleaned_data['joint_with_groups']
|
||||
check_conflict(groups, self.group)
|
||||
return groups
|
||||
|
||||
def clean(self):
|
||||
super(SessionForm, self).clean()
|
||||
data = self.cleaned_data
|
||||
|
@ -180,12 +190,20 @@ class SessionForm(forms.Form):
|
|||
if data.get('num_session','') == '2':
|
||||
if not data['length_session2']:
|
||||
raise forms.ValidationError('You must enter a length for all sessions')
|
||||
elif data.get('session_time_relation'):
|
||||
raise forms.ValidationError('Time between sessions can only be used when two sessions are requested.')
|
||||
|
||||
else:
|
||||
if data.get('session_time_relation'):
|
||||
raise forms.ValidationError('Time between sessions can only be used when two '
|
||||
'sessions are requested.')
|
||||
if data['joint_for_session'] == '2':
|
||||
raise forms.ValidationError('The second session can not be the joint session, '
|
||||
'because you have not requested a second session.')
|
||||
|
||||
if data.get('third_session',False):
|
||||
if not data['length_session2'] or not data.get('length_session3',None):
|
||||
raise forms.ValidationError('You must enter a length for all sessions')
|
||||
elif data['joint_for_session'] == '3':
|
||||
raise forms.ValidationError('The third session can not be the joint session, '
|
||||
'because you have not requested a third session.')
|
||||
|
||||
return data
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ from ietf.meeting.models import Session, ResourceAssociation, SchedulingEvent, C
|
|||
from ietf.meeting.factories import MeetingFactory, SessionFactory
|
||||
from ietf.name.models import TimerangeName
|
||||
from ietf.person.models import Person
|
||||
from ietf.secr.sreq.forms import SessionForm
|
||||
from ietf.utils.mail import outbox, empty_outbox
|
||||
|
||||
from pyquery import PyQuery
|
||||
|
@ -82,6 +83,8 @@ class SessionRequestTestCase(TestCase):
|
|||
meeting = MeetingFactory(type_id='ietf', date=datetime.date.today())
|
||||
mars = RoleFactory(name_id='chair', person__user__username='marschairman', group__acronym='mars').group
|
||||
group2 = GroupFactory()
|
||||
group3 = GroupFactory()
|
||||
group4 = GroupFactory()
|
||||
SessionFactory(meeting=meeting,group=mars,status_id='sched')
|
||||
|
||||
url = reverse('ietf.secr.sreq.views.edit', kwargs={'acronym':'mars'})
|
||||
|
@ -96,6 +99,8 @@ class SessionRequestTestCase(TestCase):
|
|||
'comments':'need lights',
|
||||
'session_time_relation': 'subsequent-days',
|
||||
'adjacent_with_wg': group2.acronym,
|
||||
'joint_with_groups': group3.acronym + ' ' + group4.acronym,
|
||||
'joint_for_session': '2',
|
||||
'timeranges': ['thursday-afternoon-early', 'thursday-afternoon-late'],
|
||||
'submit': 'Continue'}
|
||||
r = self.client.post(url, post_data, HTTP_HOST='example.com')
|
||||
|
@ -112,12 +117,43 @@ class SessionRequestTestCase(TestCase):
|
|||
list(session.constraints().get(name='timerange').timeranges.all().values('name')),
|
||||
list(TimerangeName.objects.filter(name__in=['thursday-afternoon-early', 'thursday-afternoon-late']).values('name'))
|
||||
)
|
||||
|
||||
self.assertFalse(sessions[0].joint_with_groups.count())
|
||||
self.assertEqual(list(sessions[1].joint_with_groups.all()), [group3, group4])
|
||||
|
||||
# Check whether the updated data is visible on the view page
|
||||
r = self.client.get(redirect_url)
|
||||
self.assertContains(r, 'Schedule the sessions on subsequent days')
|
||||
self.assertContains(r, 'Thursday early afternoon, Thursday late afternoon')
|
||||
self.assertContains(r, group2.acronym)
|
||||
self.assertContains(r, 'Second session with: {} {}'.format(group3.acronym, group4.acronym))
|
||||
|
||||
# Edit again, changing the joint sessions and clearing some fields. The behaviour of
|
||||
# edit is different depending on whether previous joint sessions were recorded.
|
||||
post_data = {'num_session':'2',
|
||||
'length_session1':'3600',
|
||||
'length_session2':'3600',
|
||||
'attendees':'10',
|
||||
'conflict1':'',
|
||||
'comments':'need lights',
|
||||
'joint_with_groups': group2.acronym,
|
||||
'joint_for_session': '1',
|
||||
'submit': 'Continue'}
|
||||
r = self.client.post(url, post_data, HTTP_HOST='example.com')
|
||||
self.assertRedirects(r, redirect_url)
|
||||
|
||||
# Check whether updates were stored in the database
|
||||
sessions = Session.objects.filter(meeting=meeting, group=mars)
|
||||
self.assertEqual(len(sessions), 2)
|
||||
session = sessions[0]
|
||||
self.assertFalse(session.constraints().filter(name='time_relation'))
|
||||
self.assertFalse(session.constraints().filter(name='wg_adjacent'))
|
||||
self.assertFalse(session.constraints().filter(name='timerange'))
|
||||
self.assertEqual(list(sessions[0].joint_with_groups.all()), [group2])
|
||||
self.assertFalse(sessions[1].joint_with_groups.count())
|
||||
|
||||
# Check whether the updated data is visible on the view page
|
||||
r = self.client.get(redirect_url)
|
||||
self.assertContains(r, 'First session with: {}'.format(group2.acronym))
|
||||
|
||||
def test_tool_status(self):
|
||||
MeetingFactory(type_id='ietf', date=datetime.date.today())
|
||||
|
@ -135,6 +171,8 @@ class SubmitRequestCase(TestCase):
|
|||
area = RoleFactory(name_id='ad', person=ad, group__type_id='area').group
|
||||
group = GroupFactory(parent=area)
|
||||
group2 = GroupFactory(parent=area)
|
||||
group3 = GroupFactory(parent=area)
|
||||
group4 = GroupFactory(parent=area)
|
||||
session_count_before = Session.objects.filter(meeting=meeting, group=group).count()
|
||||
url = reverse('ietf.secr.sreq.views.new',kwargs={'acronym':group.acronym})
|
||||
confirm_url = reverse('ietf.secr.sreq.views.confirm',kwargs={'acronym':group.acronym})
|
||||
|
@ -146,6 +184,8 @@ class SubmitRequestCase(TestCase):
|
|||
'comments':'need projector',
|
||||
'adjacent_with_wg': group2.acronym,
|
||||
'timeranges': ['thursday-afternoon-early', 'thursday-afternoon-late'],
|
||||
'joint_with_groups': group3.acronym + ' ' + group4.acronym,
|
||||
'joint_for_session': '1',
|
||||
'submit': 'Continue'}
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
r = self.client.post(url,post_data)
|
||||
|
@ -154,6 +194,7 @@ class SubmitRequestCase(TestCase):
|
|||
# Verify the contents of the confirm view
|
||||
self.assertContains(r, 'Thursday early afternoon, Thursday late afternoon')
|
||||
self.assertContains(r, group2.acronym)
|
||||
self.assertContains(r, 'First session with: {} {}'.format(group3.acronym, group4.acronym))
|
||||
|
||||
post_data['submit'] = 'Submit'
|
||||
r = self.client.post(confirm_url,post_data)
|
||||
|
@ -166,6 +207,15 @@ class SubmitRequestCase(TestCase):
|
|||
self.assertRedirects(r, main_url)
|
||||
session_count_after = Session.objects.filter(meeting=meeting, group=group, type='regular').count()
|
||||
self.assertEqual(session_count_after, session_count_before + 1)
|
||||
|
||||
# Verify database content
|
||||
session = Session.objects.get(meeting=meeting, group=group)
|
||||
self.assertEqual(session.constraints().get(name='wg_adjacent').target.acronym, group2.acronym)
|
||||
self.assertEqual(
|
||||
list(session.constraints().get(name='timerange').timeranges.all().values('name')),
|
||||
list(TimerangeName.objects.filter(name__in=['thursday-afternoon-early', 'thursday-afternoon-late']).values('name'))
|
||||
)
|
||||
self.assertEqual(list(session.joint_with_groups.all()), [group3, group4])
|
||||
|
||||
def test_submit_request_invalid(self):
|
||||
MeetingFactory(type_id='ietf', date=datetime.date.today())
|
||||
|
@ -237,6 +287,7 @@ class SubmitRequestCase(TestCase):
|
|||
RoleFactory(name_id='ad', person=ad, group=area)
|
||||
group = GroupFactory(acronym='ames', parent=area)
|
||||
group2 = GroupFactory(acronym='ames2', parent=area)
|
||||
group3 = GroupFactory(acronym='ames2', parent=area)
|
||||
RoleFactory(name_id='chair', group=group, person__user__username='ameschairman')
|
||||
resource = ResourceAssociation.objects.create(name_id='project')
|
||||
# Bit of a test data hack - the fixture now has no used resources to pick from
|
||||
|
@ -256,6 +307,8 @@ class SubmitRequestCase(TestCase):
|
|||
'resources': resource.pk,
|
||||
'session_time_relation': 'subsequent-days',
|
||||
'adjacent_with_wg': group2.acronym,
|
||||
'joint_with_groups': group3.acronym,
|
||||
'joint_for_session': '2',
|
||||
'timeranges': ['thursday-afternoon-early', 'thursday-afternoon-late'],
|
||||
'submit': 'Continue'}
|
||||
self.client.login(username="ameschairman", password="ameschairman+password")
|
||||
|
@ -284,10 +337,11 @@ class SubmitRequestCase(TestCase):
|
|||
list(TimerangeName.objects.filter(name__in=['thursday-afternoon-early', 'thursday-afternoon-late']).values('name'))
|
||||
)
|
||||
resource = session.resources.first()
|
||||
self.assertTrue(resource.desc in notification_payload)
|
||||
self.assertTrue('Schedule the sessions on subsequent days' in notification_payload)
|
||||
self.assertTrue(group2.acronym in notification_payload)
|
||||
self.assertTrue("Can't meet: Thursday early afternoon, Thursday late" in notification_payload)
|
||||
self.assertTrue(resource.desc in notification_payload)
|
||||
self.assertTrue('Second session joint with: {}'.format(group3.acronym) in notification_payload)
|
||||
self.assertTrue(ad.ascii_name() in notification_payload)
|
||||
|
||||
class LockAppTestCase(TestCase):
|
||||
|
@ -359,9 +413,133 @@ class NotMeetingCase(TestCase):
|
|||
class RetrievePreviousCase(TestCase):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
# test error if already scheduled
|
||||
# test get previous exists/doesn't exist
|
||||
# test that groups scheduled and unscheduled add up to total groups
|
||||
# test access by unauthorized
|
||||
|
||||
|
||||
class SessionFormTest(TestCase):
|
||||
def setUp(self):
|
||||
self.group1 = GroupFactory()
|
||||
self.group2 = GroupFactory()
|
||||
self.group3 = GroupFactory()
|
||||
self.group4 = GroupFactory()
|
||||
self.group5 = GroupFactory()
|
||||
self.group6 = GroupFactory()
|
||||
|
||||
self.valid_form_data = {
|
||||
'num_session': '2',
|
||||
'third_session': 'true',
|
||||
'length_session1': '3600',
|
||||
'length_session2': '3600',
|
||||
'length_session3': '3600',
|
||||
'attendees': '10',
|
||||
'conflict1': self.group2.acronym,
|
||||
'conflict2': self.group3.acronym,
|
||||
'conflict3': self.group4.acronym,
|
||||
'comments': 'need lights',
|
||||
'session_time_relation': 'subsequent-days',
|
||||
'adjacent_with_wg': self.group5.acronym,
|
||||
'joint_with_groups': self.group6.acronym,
|
||||
'joint_for_session': '3',
|
||||
'timeranges': ['thursday-afternoon-early', 'thursday-afternoon-late'],
|
||||
'submit': 'Continue'
|
||||
}
|
||||
|
||||
def test_valid(self):
|
||||
# Test with three sessions
|
||||
form = SessionForm(data=self.valid_form_data, group=self.group1)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
# Test with two sessions
|
||||
self.valid_form_data.update({
|
||||
'length_session3': '',
|
||||
'third_session': '',
|
||||
'joint_for_session': '2'
|
||||
})
|
||||
form = SessionForm(data=self.valid_form_data, group=self.group1)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
# Test with one session
|
||||
self.valid_form_data.update({
|
||||
'length_session2': '',
|
||||
'num_session': 1,
|
||||
'joint_for_session': '1',
|
||||
'session_time_relation': '',
|
||||
})
|
||||
form = SessionForm(data=self.valid_form_data, group=self.group1)
|
||||
self.assertTrue(form.is_valid())
|
||||
|
||||
def test_invalid_groups(self):
|
||||
new_form_data = {
|
||||
'conflict1': 'doesnotexist',
|
||||
'conflict2': 'doesnotexist',
|
||||
'conflict3': 'doesnotexist',
|
||||
'adjacent_with_wg': 'doesnotexist',
|
||||
'joint_with_groups': 'doesnotexist',
|
||||
}
|
||||
form = self._invalid_test_helper(new_form_data)
|
||||
self.assertEqual(set(form.errors.keys()), set(new_form_data.keys()))
|
||||
|
||||
def test_invalid_group_appears_in_multiple_conflicts(self):
|
||||
new_form_data = {
|
||||
'conflict1': self.group2.acronym,
|
||||
'conflict2': self.group2.acronym,
|
||||
}
|
||||
form = self._invalid_test_helper(new_form_data)
|
||||
self.assertEqual(form.non_field_errors(), ['%s appears in conflicts more than once' % self.group2.acronym])
|
||||
|
||||
def test_invalid_conflict_with_self(self):
|
||||
new_form_data = {
|
||||
'conflict1': self.group1.acronym,
|
||||
}
|
||||
self._invalid_test_helper(new_form_data)
|
||||
|
||||
def test_invalid_session_time_relation(self):
|
||||
form = self._invalid_test_helper({
|
||||
'third_session': '',
|
||||
'length_session2': '',
|
||||
'num_session': 1,
|
||||
'joint_for_session': '1',
|
||||
})
|
||||
self.assertEqual(form.non_field_errors(), ['Time between sessions can only be used when two '
|
||||
'sessions are requested.'])
|
||||
|
||||
def test_invalid_joint_for_session(self):
|
||||
form = self._invalid_test_helper({
|
||||
'third_session': '',
|
||||
'num_session': 2,
|
||||
'joint_for_session': '3',
|
||||
})
|
||||
self.assertEqual(form.non_field_errors(), ['The third session can not be the joint session, '
|
||||
'because you have not requested a third session.'])
|
||||
|
||||
form = self._invalid_test_helper({
|
||||
'third_session': '',
|
||||
'length_session2': '',
|
||||
'num_session': 1,
|
||||
'joint_for_session': '2',
|
||||
'session_time_relation': '',
|
||||
})
|
||||
self.assertEqual(form.non_field_errors(), ['The second session can not be the joint session, '
|
||||
'because you have not requested a second session.'])
|
||||
|
||||
def test_invalid_missing_session_length(self):
|
||||
form = self._invalid_test_helper({
|
||||
'length_session2': '',
|
||||
'third_session': 'true',
|
||||
})
|
||||
self.assertEqual(form.non_field_errors(), ['You must enter a length for all sessions'])
|
||||
|
||||
form = self._invalid_test_helper({'length_session2': ''})
|
||||
self.assertEqual(form.non_field_errors(), ['You must enter a length for all sessions'])
|
||||
|
||||
form = self._invalid_test_helper({'length_session3': ''})
|
||||
self.assertEqual(form.non_field_errors(), ['You must enter a length for all sessions'])
|
||||
|
||||
def _invalid_test_helper(self, new_form_data):
|
||||
form_data = dict(self.valid_form_data, **new_form_data)
|
||||
form = SessionForm(data=form_data, group=self.group1)
|
||||
self.assertFalse(form.is_valid())
|
||||
return form
|
|
@ -21,7 +21,7 @@ from ietf.meeting.models import Meeting, Session, Constraint, ResourceAssociatio
|
|||
from ietf.meeting.helpers import get_meeting
|
||||
from ietf.meeting.utils import add_event_info_to_session_qs
|
||||
from ietf.name.models import SessionStatusName, ConstraintName
|
||||
from ietf.secr.sreq.forms import SessionForm, ToolStatusForm, allowed_conflicting_groups
|
||||
from ietf.secr.sreq.forms import SessionForm, ToolStatusForm, allowed_conflicting_groups, JOINT_FOR_SESSION_CHOICES
|
||||
from ietf.secr.utils.decorators import check_permissions
|
||||
from ietf.secr.utils.group import get_my_groups
|
||||
from ietf.utils.mail import send_mail
|
||||
|
@ -88,6 +88,11 @@ def get_initial_session(sessions, prune_conflicts=False):
|
|||
timeranges = conflicts.filter(name__slug='timerange')
|
||||
initial['timeranges'] = timeranges[0].timeranges.all() if timeranges else []
|
||||
initial['timeranges_display'] = [t.desc for t in initial['timeranges']]
|
||||
for idx, session in enumerate(sessions):
|
||||
if session.joint_with_groups.count():
|
||||
initial['joint_with_groups'] = ' '.join(session.joint_with_groups_acronyms())
|
||||
initial['joint_for_session'] = str(idx + 1)
|
||||
initial['joint_for_session_display'] = dict(JOINT_FOR_SESSION_CHOICES)[initial['joint_for_session']]
|
||||
return initial
|
||||
|
||||
def get_lock_message(meeting=None):
|
||||
|
@ -273,6 +278,8 @@ def confirm(request, acronym):
|
|||
session_data['bethere'] = Person.objects.filter(pk__in=person_id_list)
|
||||
if session_data.get('session_time_relation'):
|
||||
session_data['session_time_relation_display'] = dict(Constraint.TIME_RELATION_CHOICES)[session_data['session_time_relation']]
|
||||
if session_data.get('joint_for_session'):
|
||||
session_data['joint_for_session_display'] = dict(JOINT_FOR_SESSION_CHOICES)[session_data['joint_for_session']]
|
||||
if form.cleaned_data.get('timeranges'):
|
||||
session_data['timeranges_display'] = [t.desc for t in form.cleaned_data['timeranges']]
|
||||
session_data['resources'] = [ ResourceAssociation.objects.get(pk=pk) for pk in request.POST.getlist('resources') ]
|
||||
|
@ -314,6 +321,10 @@ def confirm(request, acronym):
|
|||
)
|
||||
if 'resources' in form.data:
|
||||
new_session.resources.set(session_data['resources'])
|
||||
if int(form.data.get('joint_for_session', '-1')) == count:
|
||||
groups_split = form.cleaned_data.get('joint_with_groups').replace(',',' ').split()
|
||||
joint = Group.objects.filter(acronym__in=groups_split)
|
||||
new_session.joint_with_groups.set(joint)
|
||||
session_changed(new_session)
|
||||
|
||||
# write constraint records
|
||||
|
@ -469,7 +480,30 @@ def edit(request, acronym, num=None):
|
|||
session.save()
|
||||
session_changed(session)
|
||||
|
||||
# New sessions may have been created, refresh the sessions list
|
||||
sessions = add_event_info_to_session_qs(
|
||||
Session.objects.filter(group=group, meeting=meeting)).filter(
|
||||
Q(current_status__isnull=True) | ~Q(
|
||||
current_status__in=['canceled', 'notmeet'])).order_by('id')
|
||||
|
||||
if 'joint_with_groups' in form.changed_data or 'joint_for_session' in form.changed_data:
|
||||
joint_with_groups_list = form.cleaned_data.get('joint_with_groups').replace(',', ' ').split()
|
||||
new_joint_with_groups = Group.objects.filter(acronym__in=joint_with_groups_list)
|
||||
new_joint_for_session_idx = int(form.data.get('joint_for_session', '-1')) - 1
|
||||
current_joint_for_session_idx = None
|
||||
current_joint_with_groups = None
|
||||
for idx, session in enumerate(sessions):
|
||||
if session.joint_with_groups.count():
|
||||
current_joint_for_session_idx = idx
|
||||
current_joint_with_groups = session.joint_with_groups.all()
|
||||
|
||||
if current_joint_with_groups != new_joint_with_groups or current_joint_for_session_idx != new_joint_for_session_idx:
|
||||
if current_joint_for_session_idx is not None:
|
||||
sessions[current_joint_for_session_idx].joint_with_groups.clear()
|
||||
session_changed(sessions[current_joint_for_session_idx])
|
||||
sessions[new_joint_for_session_idx].joint_with_groups.set(new_joint_with_groups)
|
||||
session_changed(sessions[new_joint_for_session_idx])
|
||||
|
||||
if 'attendees' in form.changed_data:
|
||||
sessions.update(attendees=form.cleaned_data['attendees'])
|
||||
if 'comments' in form.changed_data:
|
||||
|
|
|
@ -15,28 +15,34 @@ function stat_ls (val){
|
|||
if (val == 0) {
|
||||
document.form_post.length_session1.disabled = true;
|
||||
document.form_post.length_session2.disabled = true;
|
||||
document.form_post.length_session3.disabled = true;
|
||||
if (document.form_post.length_session3) { document.form_post.length_session3.disabled = true; }
|
||||
document.form_post.session_time_relation.disabled = true;
|
||||
document.form_post.joint_for_session.disabled = true;
|
||||
document.form_post.length_session1.value = 0;
|
||||
document.form_post.length_session2.value = 0;
|
||||
document.form_post.length_session3.value = 0;
|
||||
document.form_post.session_time_relation.value = '';
|
||||
document.form_post.joint_for_session.value = '';
|
||||
document.form_post.third_session.checked=false;
|
||||
}
|
||||
if (val == 1) {
|
||||
document.form_post.length_session1.disabled = false;
|
||||
document.form_post.length_session2.disabled = true;
|
||||
document.form_post.length_session3.disabled = true;
|
||||
if (document.form_post.length_session3) { document.form_post.length_session3.disabled = true; }
|
||||
document.form_post.session_time_relation.disabled = true;
|
||||
document.form_post.joint_for_session.disabled = true;
|
||||
document.form_post.length_session2.value = 0;
|
||||
document.form_post.length_session3.value = 0;
|
||||
document.form_post.session_time_relation.value = '';
|
||||
document.form_post.joint_for_session.value = '1';
|
||||
document.form_post.third_session.checked=false;
|
||||
}
|
||||
if (val == 2) {
|
||||
document.form_post.length_session1.disabled = false;
|
||||
document.form_post.length_session2.disabled = false;
|
||||
if (document.form_post.length_session3) { document.form_post.length_session3.disabled = false; }
|
||||
document.form_post.session_time_relation.disabled = false;
|
||||
document.form_post.joint_for_session.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,6 +122,15 @@ function delete_last3 () {
|
|||
document.form_post.conflict3.value = b;
|
||||
document.form_post.wg_selector3.selectedIndex=0;
|
||||
}
|
||||
function delete_last_joint_with_groups () {
|
||||
var b = document.form_post.joint_with_groups.value;
|
||||
var temp = new Array();
|
||||
temp = b.split(' ');
|
||||
temp.pop();
|
||||
b = temp.join(' ');
|
||||
document.form_post.joint_with_groups.value = b;
|
||||
document.form_post.wg_selector4.selectedIndex=0;
|
||||
}
|
||||
|
||||
// Not calling check_prior_confict (see ietf/secr/sreq/forms.py definition of SessionForm)
|
||||
// while we are hacking the use of the current three constraint types around. We could bring
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
Working Group Name: {{ group.name }}
|
||||
Area Name: {{ group.parent }}
|
||||
Session Requester: {{ login }}
|
||||
{% if session.joint_with_groups %}{{ session.joint_for_session_display }} joint with: {{ session.joint_with_groups }}{% endif %}
|
||||
|
||||
Number of Sessions: {{ session.num_session }}
|
||||
Length of Session(s): {{ session.length_session1|display_duration }}{% if session.length_session2 %}, {{ session.length_session2|display_duration }}{% endif %}{% if session.length_session3 %}, {{ session.length_session3|display_duration }}{% endif %}
|
||||
|
|
|
@ -72,6 +72,22 @@
|
|||
<td>{{ form.adjacent_with_wg.errors }}{{ form.adjacent_with_wg }}</td>
|
||||
</tr>
|
||||
<tr class="bg1">
|
||||
<td>
|
||||
Joint session with:<br />
|
||||
(To request one session for multiple WGs together.)
|
||||
</td>
|
||||
<td>{{ form.wg_selector4 }}
|
||||
<input type="button" value="Delete the last entry" onClick="delete_last_joint_with_groups(); return 1;"><br>
|
||||
{{ form.joint_with_groups.errors }}{{ form.joint_with_groups }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="bg1">
|
||||
<td>
|
||||
Of the sessions requested by this WG, the joint session, if applicable, is:
|
||||
</td>
|
||||
<td>{{ form.joint_for_session.errors }}{{ form.joint_for_session }}</td>
|
||||
</tr>
|
||||
<tr class="bg2">
|
||||
<td valign="top">Special Requests:<br /> <br />i.e. restrictions on meeting times / days, etc.</td>
|
||||
<td>{{ form.comments.errors }}{{ form.comments }}</td>
|
||||
</tr>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<tr class="row2"><td>Length of Session 1:</td><td>{{ session.length_session1|display_duration }}</td></tr>
|
||||
{% if session.length_session2 %}
|
||||
<tr class="row2"><td>Length of Session 2:</td><td>{{ session.length_session2|display_duration }}</td></tr>
|
||||
<tr class="row2"><td>Time between sessions:</td><td>{{ session.session_time_relation_display|default:"No preference" }}</td></tr>
|
||||
<tr class="row2"><td>Time between sessions:</td><td>{% if session.session_time_relation_display %}{{ session.session_time_relation_display }}{% else %}No preference{% endif %}</td></tr>
|
||||
{% endif %}
|
||||
{% if session.length_session3 %}
|
||||
<tr class="row2"><td>Length of Session 3:</td><td>{{ session.length_session3|display_duration }}</td></tr>
|
||||
|
@ -42,7 +42,17 @@
|
|||
<td>Adjacent with WG:</td>
|
||||
<td>{{ session.adjacent_with_wg|default:'No preference' }}</td>
|
||||
</tr>
|
||||
<tr class="row2">
|
||||
<td>Joint session:</td>
|
||||
<td>
|
||||
{% if session.joint_with_groups %}
|
||||
{{ session.joint_for_session_display }} with: {{ session.joint_with_groups }}
|
||||
{% else %}
|
||||
Not a joint session
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% autoescape off %}
|
||||
<tr class="row2"><td>Special Requests:</td><td>{{ session.comments }}</td></tr>
|
||||
<tr class="row1"><td>Special Requests:</td><td>{{ session.comments }}</td></tr>
|
||||
{% endautoescape %}
|
||||
</table>
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
<a href="{% url "ietf.secr.sreq.views.edit" num=meeting.number acronym=session.group.acronym %}">
|
||||
{{session.group.acronym}}
|
||||
</a>
|
||||
{% if session.joint_with_groups.count %}
|
||||
joint with {{ session.joint_with_groups_acronyms|join:' ' }}
|
||||
{% endif %}
|
||||
</th>
|
||||
|
||||
<td class="text-right">
|
||||
|
|
Loading…
Reference in a new issue