Merged in [15787] from rcross@amsl.com:
Rework page flow and forms of secr/meetings app. Fixes #2609.
- Legacy-Id: 15794
Note: SVN reference [15787] has been migrated to Git commit e634dc2488
This commit is contained in:
commit
e55a079591
|
@ -1,4 +1,3 @@
|
|||
import datetime
|
||||
import re
|
||||
|
||||
from django import forms
|
||||
|
@ -130,44 +129,6 @@ class MeetingRoomForm(forms.ModelForm):
|
|||
model = Room
|
||||
exclude = ['resources']
|
||||
|
||||
class NewSessionForm(forms.Form):
|
||||
day = forms.ChoiceField(choices=SESSION_DAYS)
|
||||
time = TimeChoiceField()
|
||||
room = forms.ModelChoiceField(queryset=Room.objects.none())
|
||||
session = forms.CharField(widget=forms.HiddenInput)
|
||||
note = forms.CharField(max_length=255, required=False, label='Special Note from Scheduler')
|
||||
combine = forms.BooleanField(required=False, label='Combine with next session')
|
||||
|
||||
# setup the timeslot options based on meeting passed in
|
||||
def __init__(self,*args,**kwargs):
|
||||
self.meeting = kwargs.pop('meeting')
|
||||
super(NewSessionForm, self).__init__(*args,**kwargs)
|
||||
|
||||
# attach session object to the form so we can use it in the template
|
||||
self.session_object = Session.objects.get(id=self.initial['session'])
|
||||
self.fields['room'].queryset = Room.objects.filter(meeting=self.meeting)
|
||||
self.fields['time'].choices = get_times(self.meeting,self.initial['day'])
|
||||
|
||||
def clean(self):
|
||||
super(NewSessionForm, self).clean()
|
||||
if any(self.errors):
|
||||
return
|
||||
cleaned_data = self.cleaned_data
|
||||
time = cleaned_data['time']
|
||||
day = cleaned_data['day']
|
||||
room = cleaned_data['room']
|
||||
if cleaned_data['combine']:
|
||||
# calculate datetime object from inputs, get current slot, feed to get_next_slot()
|
||||
day_obj = self.meeting.get_meeting_date(int(day)-1)
|
||||
hour = datetime.time(int(time[:2]),int(time[2:]))
|
||||
time_obj = datetime.datetime.combine(day_obj,hour)
|
||||
slot = TimeSlot.objects.get(meeting=self.meeting,time=time_obj,location=room)
|
||||
next_slot = get_next_slot(slot)
|
||||
if not next_slot:
|
||||
raise forms.ValidationError('There is no next session to combine')
|
||||
|
||||
return cleaned_data
|
||||
|
||||
class TimeSlotForm(forms.Form):
|
||||
day = forms.ChoiceField(choices=DAYS_CHOICES)
|
||||
time = forms.TimeField()
|
||||
|
|
|
@ -102,12 +102,9 @@ class SecrMeetingTestCase(TestCase):
|
|||
|
||||
def test_edit_meeting(self):
|
||||
"Edit Meeting"
|
||||
Meeting.objects.create(number=1,
|
||||
type_id='ietf',
|
||||
date=datetime.datetime(2014,7,20),
|
||||
)
|
||||
url = reverse('ietf.secr.meetings.views.edit_meeting',kwargs={'meeting_id':1})
|
||||
post_data = dict(number='1',date='2014-07-20',city='Toronto',
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('ietf.secr.meetings.views.edit_meeting',kwargs={'meeting_id':meeting.number})
|
||||
post_data = dict(number=meeting.number,date='2014-07-20',city='Toronto',
|
||||
days=7,
|
||||
idsubmit_cutoff_day_offset_00=13,
|
||||
idsubmit_cutoff_day_offset_01=20,
|
||||
|
@ -119,9 +116,9 @@ class SecrMeetingTestCase(TestCase):
|
|||
attendees=1234,
|
||||
)
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.post(url, post_data,follow=True)
|
||||
response = self.client.post(url, post_data, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
meeting = Meeting.objects.get(number=1)
|
||||
meeting = Meeting.objects.get(number=meeting.number)
|
||||
self.assertEqual(meeting.city,'Toronto')
|
||||
self.assertEqual(meeting.attendees,1234)
|
||||
|
||||
|
@ -187,13 +184,6 @@ class SecrMeetingTestCase(TestCase):
|
|||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(len(outbox), mailbox_before + 1)
|
||||
|
||||
def test_meetings_select(self):
|
||||
make_meeting_test_data()
|
||||
url = reverse('ietf.secr.meetings.views.select',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_meetings_rooms(self):
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('ietf.secr.meetings.views.rooms',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
|
@ -370,31 +360,11 @@ class SecrMeetingTestCase(TestCase):
|
|||
session = slot.sessionassignments.filter(schedule=meeting.agenda).first().session
|
||||
self.assertEqual(session.status_id, 'canceled')
|
||||
|
||||
def test_meetings_select_group(self):
|
||||
make_meeting_test_data()
|
||||
url = reverse('ietf.secr.meetings.views.select_group',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
q = PyQuery(response.content)
|
||||
self.assertEqual(len(q("#id_scheduled_sessions")),1)
|
||||
|
||||
def test_meetings_schedule(self):
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('ietf.secr.meetings.views.schedule',kwargs={
|
||||
'meeting_id':meeting.number,
|
||||
'schedule_name':meeting.agenda.name,
|
||||
'acronym':'mars'
|
||||
})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_meetings_session_edit(self):
|
||||
meeting = make_meeting_test_data()
|
||||
session = Session.objects.filter(meeting=meeting,group__acronym='mars').first()
|
||||
url = reverse('ietf.secr.meetings.views.session_edit', kwargs={'meeting_id':meeting.number,'schedule_name':meeting.agenda.name,'session_id':session.id})
|
||||
redirect_url = reverse('ietf.secr.meetings.views.select_group', kwargs={'meeting_id':meeting.number,'schedule_name':meeting.agenda.name})
|
||||
redirect_url = reverse('ietf.secr.meetings.views.sessions', kwargs={'meeting_id':meeting.number,'schedule_name':meeting.agenda.name})
|
||||
self.client.login(username="secretary", password="secretary+password")
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
@ -402,10 +372,6 @@ class SecrMeetingTestCase(TestCase):
|
|||
self.assertRedirects(response, redirect_url)
|
||||
session = Session.objects.get(id=session.id)
|
||||
self.assertEqual(session.agenda_note, 'TEST')
|
||||
response = self.client.post(url, {'agenda_note':'TEST','submit':'Cancel'})
|
||||
self.assertRedirects(response, redirect_url)
|
||||
session = Session.objects.get(id=session.id)
|
||||
self.assertEqual(session.status.slug, 'canceled')
|
||||
|
||||
# ----------------------
|
||||
# Unit Tests
|
||||
|
|
|
@ -12,18 +12,15 @@ urlpatterns = [
|
|||
url(r'^(?P<meeting_id>\d{1,6})/blue_sheet/generate/$', views.blue_sheet_generate),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/edit/$', views.edit_meeting),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/notifications/$', views.notifications),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/$', views.select),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/$', views.rooms),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/non_session/$', views.non_session),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/non_session/cancel/(?P<slot_id>\d{1,6})/$', views.non_session_cancel),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/non_session/edit/(?P<slot_id>\d{1,6})/$', views.non_session_edit),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/non_session/delete/(?P<slot_id>\d{1,6})/$', views.non_session_delete),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/rooms/$', views.rooms),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/select/$', views.select_group),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/times/$', views.times),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/sessions/$', views.sessions),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/times/delete/(?P<time>[0-9\:]+)/$', views.times_delete),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/times/edit/(?P<time>[0-9\:]+)/$', views.times_edit),
|
||||
# url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/unschedule/(?P<session_id>\d{1,6})/$', views.unschedule), # Not in use
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/(?P<acronym>[-a-z0-9]+)/schedule/$', views.schedule),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/(?P<session_id>\d{1,6})/edit/$', views.session_edit),
|
||||
url(r'^(?P<meeting_id>\d{1,6})/(?P<acronym>[-a-z0-9]+)/remove/$', views.remove_session),
|
||||
]
|
||||
|
|
|
@ -5,10 +5,8 @@ import time
|
|||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.db.models import Max
|
||||
from django.forms.formsets import formset_factory
|
||||
from django.forms.models import inlineformset_factory
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.utils.functional import curry
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
|
@ -22,8 +20,8 @@ from ietf.group.models import Group, GroupEvent
|
|||
from ietf.person.models import Person
|
||||
from ietf.secr.meetings.blue_sheets import create_blue_sheets
|
||||
from ietf.secr.meetings.forms import ( BaseMeetingRoomFormSet, MeetingModelForm, MeetingSelectForm,
|
||||
MeetingRoomForm, NewSessionForm, NonSessionForm, TimeSlotForm, SessionEditForm,
|
||||
UploadBlueSheetForm, get_next_slot )
|
||||
MeetingRoomForm, NonSessionForm, TimeSlotForm, SessionEditForm,
|
||||
UploadBlueSheetForm )
|
||||
from ietf.secr.proceedings.utils import handle_upload_file
|
||||
from ietf.secr.sreq.views import get_initial_session
|
||||
from ietf.secr.utils.meeting import get_session, get_timeslot
|
||||
|
@ -489,7 +487,8 @@ def non_session(request, meeting_id, schedule_name):
|
|||
'assignments': assignments,
|
||||
'form': form,
|
||||
'meeting': meeting,
|
||||
'schedule': schedule},
|
||||
'schedule': schedule,
|
||||
'selected': 'non-sessions'},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
|
@ -636,32 +635,6 @@ def notifications(request, meeting_id):
|
|||
'last_notice': last_notice },
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def remove_session(request, meeting_id, acronym):
|
||||
'''
|
||||
Remove session from agenda. Disassociate session from timeslot and set status.
|
||||
According to Wanda this option is used when people cancel, so the Session
|
||||
request should be deleted as well.
|
||||
'''
|
||||
from ietf.utils import log
|
||||
log.unreachable("2017-07-08")
|
||||
meeting = get_object_or_404(Meeting, number=meeting_id)
|
||||
group = get_object_or_404(Group, acronym=acronym)
|
||||
sessions = Session.objects.filter(meeting=meeting,group=group)
|
||||
now = datetime.datetime.now()
|
||||
|
||||
for session in sessions:
|
||||
ss = session.official_timeslotassignment()
|
||||
ss.session = None
|
||||
ss.modified = now
|
||||
ss.save()
|
||||
session.status_id = 'canceled'
|
||||
session.modified = now
|
||||
session.save()
|
||||
|
||||
messages.success(request, '%s Session removed from agenda' % (group.acronym))
|
||||
return redirect('ietf.secr.meetings.views.select_group', meeting_id=meeting.number)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def rooms(request, meeting_id, schedule_name):
|
||||
'''
|
||||
|
@ -703,154 +676,39 @@ def rooms(request, meeting_id, schedule_name):
|
|||
return render(request, 'meetings/rooms.html', {
|
||||
'meeting': meeting,
|
||||
'schedule': schedule,
|
||||
'formset': formset},
|
||||
'formset': formset,
|
||||
'selected': 'rooms'}
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def schedule(request, meeting_id, schedule_name, acronym):
|
||||
def sessions(request, meeting_id, schedule_name):
|
||||
'''
|
||||
This view handles scheduling session requests to TimeSlots
|
||||
Display and edit Session records for the specified meeting
|
||||
'''
|
||||
meeting = get_object_or_404(Meeting, number=meeting_id)
|
||||
schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name)
|
||||
group = get_object_or_404(Group, acronym=acronym)
|
||||
sessions = schedule.sessions_that_can_meet.order_by('group__acronym')
|
||||
|
||||
sessions = Session.objects.filter(meeting=meeting,group=group,status__in=('schedw','apprw','appr','sched','canceled'))
|
||||
legacy_session = get_initial_session(sessions)
|
||||
now = datetime.datetime.now()
|
||||
|
||||
# build initial
|
||||
initial = []
|
||||
for s in sessions:
|
||||
d = {'session':s.id,
|
||||
'note':s.agenda_note}
|
||||
timeslot = get_timeslot(s, schedule=schedule)
|
||||
|
||||
if timeslot:
|
||||
d['room'] = timeslot.location.id if timeslot.location else None
|
||||
d['day'] = timeslot.time.isoweekday() % 7 + 1 # adjust to django week_day
|
||||
d['time'] = timeslot.time.strftime('%H%M')
|
||||
else:
|
||||
d['day'] = 2 # default
|
||||
if is_combined(s,meeting,schedule=schedule):
|
||||
d['combine'] = True
|
||||
initial.append(d)
|
||||
|
||||
# need to use curry here to pass custom variable to form init
|
||||
NewSessionFormset = formset_factory(NewSessionForm, extra=0)
|
||||
NewSessionFormset.form = staticmethod(curry(NewSessionForm, meeting=meeting))
|
||||
|
||||
if request.method == 'POST':
|
||||
button_text = request.POST.get('submit', '')
|
||||
if button_text == 'Cancel':
|
||||
return redirect('ietf.secr.meetings.views.select_group', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
if 'cancel' in request.POST:
|
||||
pk = request.POST.get('pk')
|
||||
session = Session.objects.get(pk=pk)
|
||||
session.status = SessionStatusName.objects.get(slug='canceled')
|
||||
session.save()
|
||||
messages.success(request, 'Session cancelled')
|
||||
|
||||
formset = NewSessionFormset(request.POST,initial=initial)
|
||||
|
||||
if formset.is_valid():
|
||||
# TODO formsets don't have has_changed until Django 1.3
|
||||
has_changed = False
|
||||
for form in formset.forms:
|
||||
if form.has_changed():
|
||||
has_changed = True
|
||||
id = form.cleaned_data['session']
|
||||
note = form.cleaned_data['note']
|
||||
room = form.cleaned_data['room']
|
||||
time = form.cleaned_data['time']
|
||||
day = form.cleaned_data['day']
|
||||
combine = form.cleaned_data.get('combine',None)
|
||||
session = Session.objects.get(id=id)
|
||||
initial_timeslot = get_timeslot(session,schedule=schedule)
|
||||
|
||||
# find new timeslot
|
||||
new_day = meeting.date + datetime.timedelta(days=int(day)-1)
|
||||
hour = datetime.time(int(time[:2]),int(time[2:]))
|
||||
new_time = datetime.datetime.combine(new_day,hour)
|
||||
timeslot = TimeSlot.objects.filter(meeting=meeting,time=new_time,location=room)[0]
|
||||
|
||||
# COMBINE SECTION - BEFORE --------------
|
||||
if 'combine' in form.changed_data and not combine:
|
||||
next_slot = get_next_slot(initial_timeslot)
|
||||
for ss in next_slot.sessionassignments.filter(schedule=schedule,session=session):
|
||||
ss.session = None
|
||||
ss.save()
|
||||
# ---------------------------------------
|
||||
if any(x in form.changed_data for x in ('day','time','room')):
|
||||
# clear the old association
|
||||
if initial_timeslot:
|
||||
# delete schedtimesessassignment records to unschedule
|
||||
session.timeslotassignments.filter(schedule=schedule).delete()
|
||||
|
||||
if timeslot:
|
||||
assign(session,timeslot,meeting,schedule=schedule)
|
||||
if timeslot.sessions.all().count() > 1:
|
||||
messages.warning(request, 'WARNING: There are now multiple sessions scheduled for the timeslot: %s' % timeslot)
|
||||
else:
|
||||
session.status_id = 'schedw'
|
||||
|
||||
session.modified = now
|
||||
session.save()
|
||||
|
||||
if 'note' in form.changed_data:
|
||||
session.agenda_note = note
|
||||
session.modified = now
|
||||
session.save()
|
||||
|
||||
# COMBINE SECTION - AFTER ---------------
|
||||
if 'combine' in form.changed_data and combine:
|
||||
next_slot = get_next_slot(timeslot)
|
||||
assign(session,next_slot,meeting,schedule=schedule)
|
||||
# ---------------------------------------
|
||||
|
||||
if has_changed:
|
||||
messages.success(request, 'Session(s) Scheduled for %s.' % group.acronym )
|
||||
|
||||
return redirect('ietf.secr.meetings.views.select_group', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
|
||||
else:
|
||||
formset = NewSessionFormset(initial=initial)
|
||||
|
||||
return render(request, 'meetings/schedule.html', {
|
||||
'group': group,
|
||||
return render(request, 'meetings/sessions.html', {
|
||||
'meeting': meeting,
|
||||
'schedule': schedule,
|
||||
'show_request': True,
|
||||
'session': legacy_session,
|
||||
'formset': formset},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def select(request, meeting_id, schedule_name):
|
||||
'''
|
||||
Options to edit Rooms & Times or schedule a session
|
||||
'''
|
||||
meeting = get_object_or_404(Meeting, number=meeting_id)
|
||||
schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name)
|
||||
|
||||
return render(request, 'meetings/select.html', {
|
||||
'meeting': meeting,
|
||||
'schedule': schedule},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def select_group(request, meeting_id, schedule_name):
|
||||
'''
|
||||
Select the scheduled session to edit.
|
||||
'''
|
||||
meeting = get_object_or_404(Meeting, number=meeting_id)
|
||||
schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name)
|
||||
assignments = schedule.assignments.filter(timeslot__type='session').order_by('session__group__acronym')
|
||||
|
||||
return render(request, 'meetings/select_group.html', {
|
||||
'meeting': meeting,
|
||||
'schedule': schedule,
|
||||
'assignments': assignments},
|
||||
'sessions': sessions,
|
||||
'formset': None,
|
||||
'selected': 'sessions',},
|
||||
)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def session_edit(request, meeting_id, schedule_name, session_id):
|
||||
'''
|
||||
Edit session details, cancel session
|
||||
Edit session details
|
||||
'''
|
||||
meeting = get_object_or_404(Meeting, number=meeting_id)
|
||||
schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name)
|
||||
|
@ -860,15 +718,9 @@ def session_edit(request, meeting_id, schedule_name, session_id):
|
|||
if request.method == 'POST':
|
||||
form = SessionEditForm(request.POST, instance=session)
|
||||
if form.is_valid():
|
||||
button_text = request.POST.get('submit', '')
|
||||
if button_text == 'Cancel':
|
||||
session.status = SessionStatusName.objects.get(slug='canceled')
|
||||
session.save()
|
||||
messages.success(request, 'Session cancelled')
|
||||
else:
|
||||
form.save()
|
||||
messages.success(request, 'Session saved')
|
||||
return redirect('ietf.secr.meetings.views.select_group', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
form.save()
|
||||
messages.success(request, 'Session saved')
|
||||
return redirect('ietf.secr.meetings.views.sessions', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
|
||||
else:
|
||||
form = SessionEditForm(instance=session)
|
||||
|
@ -938,7 +790,8 @@ def times(request, meeting_id, schedule_name):
|
|||
'form': form,
|
||||
'meeting': meeting,
|
||||
'schedule': schedule,
|
||||
'times': times},
|
||||
'times': times,
|
||||
'selected': 'times'},
|
||||
)
|
||||
|
||||
def get_timeslot_time(form, meeting):
|
||||
|
@ -1029,23 +882,6 @@ def times_delete(request, meeting_id, schedule_name, time):
|
|||
'extra': 'Any sessions assigned to this timeslot will be unscheduled'
|
||||
})
|
||||
|
||||
# @role_required('Secretariat')
|
||||
# def unschedule(request, meeting_id, schedule_name, session_id):
|
||||
# '''
|
||||
# Unschedule given session object
|
||||
# '''
|
||||
# from ietf.utils import log
|
||||
# log.unreachable("2017-07-08")
|
||||
# meeting = get_object_or_404(Meeting, number=meeting_id)
|
||||
# session = get_object_or_404(Session, id=session_id)
|
||||
#
|
||||
# session.timeslotassignments.filter(schedule=meeting.agenda).delete()
|
||||
#
|
||||
# # TODO: change session state?
|
||||
#
|
||||
# messages.success(request, 'Session unscheduled')
|
||||
# return redirect('ietf.secr.meetings.views.select_group', meeting_id=meeting_id, schedule_name=schedule_name)
|
||||
|
||||
@role_required('Secretariat')
|
||||
def view(request, meeting_id):
|
||||
'''
|
||||
|
|
|
@ -213,25 +213,20 @@ button.fancy:hover {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
ul#list-nav {
|
||||
.list-nav {
|
||||
padding-left: 0;
|
||||
margin-left: 0;
|
||||
background-color: #36648B;
|
||||
color: White;
|
||||
/* float: left; */
|
||||
width: 100%;
|
||||
/* font-family: arial, helvetica, sans-serif; */
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
ul#list-nav li { display: inline; }
|
||||
.list-nav li { display: inline; }
|
||||
|
||||
|
||||
ul#list-nav li a {
|
||||
/*padding: 0.2em 1em; */
|
||||
.list-nav li a {
|
||||
padding: 0.2em;
|
||||
/*width: 19.1%; */
|
||||
width: 23%;
|
||||
width: 19%;
|
||||
background-color: #36648B;
|
||||
color: White;
|
||||
text-decoration: none;
|
||||
|
@ -240,16 +235,24 @@ ul#list-nav li a {
|
|||
border-left: 1px solid #fff;
|
||||
}
|
||||
|
||||
ul#list-nav li.leftmost a {
|
||||
.rooms-times-nav .list-nav li a {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.list-nav li.selected a {
|
||||
background-color: #4F94CD;
|
||||
}
|
||||
|
||||
.list-nav li.leftmost a {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
ul#list-nav li a:hover {
|
||||
.list-nav li a:hover {
|
||||
background-color: #4F94CD;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
ul#list-nav a.current {
|
||||
.list-nav a.current {
|
||||
background-color: #7CA0C7;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,33 +166,23 @@ function init_proceedings_table() {
|
|||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
// in general set focus on first input field
|
||||
$("input:text:visible:enabled:first").focus();
|
||||
|
||||
// custom focus settings --------------------------------
|
||||
if ( $("form[id^=group-role-assignment-form]").length > 0){
|
||||
// set focus --------------------------------
|
||||
if ( $("form[id^=group-role-assignment-form]").length > 0) {
|
||||
$("#id_role_type").focus();
|
||||
}
|
||||
if ( $("form[id=draft-search-form]").length > 0){
|
||||
} else if ( $("form[id=draft-search-form]").length > 0) {
|
||||
$("#id_filename").focus();
|
||||
}
|
||||
if ( $("form[id=drafts-add-form]").length > 0){
|
||||
} else if ( $("form[id=drafts-add-form]").length > 0) {
|
||||
$("#id_title").focus();
|
||||
}
|
||||
if ( $("form[id=proceedings-add-form]").length > 0){
|
||||
} else if ( $("form[id=proceedings-add-form]").length > 0) {
|
||||
$("#id_start_date").focus();
|
||||
}
|
||||
if ( $("form[id=proceedings-upload-form]").length > 0){
|
||||
} else if ( $("form[id=proceedings-upload-form]").length > 0) {
|
||||
$("#id_group_name").focus();
|
||||
}
|
||||
if ( $("form[id=session-request-form]").length > 0){
|
||||
} else if ( $("form[id=session-request-form]").length > 0) {
|
||||
$("#id_num_session").focus();
|
||||
}
|
||||
if ( $("form[id^=meetings-meta]").length > 0){
|
||||
$("button[type=submit]:first").focus();
|
||||
}
|
||||
if ( $("form[id=meetings-schedule-form]").length > 0){
|
||||
$("#id_form-0-time").focus();
|
||||
} else if ( $(".rooms-times-nav").length > 0){
|
||||
$("li.selected a").focus();
|
||||
} else {
|
||||
$("input:text:visible:enabled:first").focus();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
|
||||
<div class="button-group">
|
||||
<ul>
|
||||
<li><button type="submit" name="submit" value="Continue"{% if is_locked %} disabled{% endif %}>Continue</button></li>
|
||||
<li><button type="submit" name="submit" value="Save"{% if is_locked %} disabled{% endif %}>Save</button></li>
|
||||
<li><button type="submit" name="submit" value="Cancel">Cancel</button></li>
|
||||
</ul>
|
||||
</div> <!-- button-group -->
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
{% block breadcrumbs %}{{ block.super }}
|
||||
» <a href="{% url "ietf.secr.meetings.views.main" %}">Meetings</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.view" meeting_id=meeting.number %}">{{ meeting.number }}</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.select" meeting_id=meeting.number schedule_name=schedule.name %}">{{ schedule.name }}</a>
|
||||
» Rooms and Times
|
||||
{% endblock %}
|
||||
|
||||
|
@ -21,10 +20,11 @@
|
|||
{% block content %}
|
||||
|
||||
<div id="nav" class="rooms-times-nav">
|
||||
<ul id="list-nav">
|
||||
<li id="nav-room" class="leftmost"><a href="{% url "ietf.secr.meetings.views.rooms" meeting_id=meeting.number schedule_name=schedule.name %}">Rooms</a></li>
|
||||
<li id="nav-time"><a href="{% url "ietf.secr.meetings.views.times" meeting_id=meeting.number schedule_name=schedule.name %}">Times</a></li>
|
||||
<li id="nav-non-session"><a href="{% url "ietf.secr.meetings.views.non_session" meeting_id=meeting.number schedule_name=schedule.name %}">Non-Session</a></li>
|
||||
<ul class="list-nav">
|
||||
<li id="nav-room" class="leftmost{% if selected == 'rooms' %} selected{% endif %}"><a href="{% url "ietf.secr.meetings.views.rooms" meeting_id=meeting.number schedule_name=schedule.name %}">Rooms</a></li>
|
||||
<li id="nav-time" class="{% if selected == 'times' %}selected{% endif %}"><a href="{% url "ietf.secr.meetings.views.times" meeting_id=meeting.number schedule_name=schedule.name %}">Times</a></li>
|
||||
<li id="nav-non-session" class="{% if selected == 'non-sessions' %}selected{% endif %}"><a href="{% url "ietf.secr.meetings.views.non_session" meeting_id=meeting.number schedule_name=schedule.name %}">Non-Session</a></li>
|
||||
<li id="nav-session" class="{% if selected == 'sessions' %}selected{% endif %}"><a href="{% url "ietf.secr.meetings.views.sessions" meeting_id=meeting.number schedule_name=schedule.name %}">Sessions</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
{% extends "base_site.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Meetings{% endblock %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script type="text/javascript" src="{% static 'secr/js/utils.js' %}"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$.ajaxSetup ({
|
||||
cache: false
|
||||
});
|
||||
|
||||
$("select[id$='day']").change(function(){
|
||||
var loadUrl = "/secr/meetings/ajax/get-times/";
|
||||
var url = window.location.pathname;
|
||||
var parts = url.split("/");
|
||||
var id = this.id;
|
||||
var new_id = id.replace('day','time');
|
||||
var sel = "#"+new_id;
|
||||
var day = $(this).val();
|
||||
loadUrl = loadUrl+parts[3]+"/"+day+"/";
|
||||
$.getJSON(loadUrl,function(data) {
|
||||
$(sel+" option").remove();
|
||||
$.each(data,function(i,item) {
|
||||
$(sel).append('<option value="'+item.id+'">'+item.value+'</option>');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{{ block.super }}
|
||||
» <a href="{% url "ietf.secr.meetings.views.main" %}">Meetings</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.view" meeting_id=meeting.number %}">{{ meeting.number }}</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.select" meeting_id=meeting.number schedule_name=schedule.name %}">{{ schedule.name }}</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.select_group" meeting_id=meeting.number schedule_name=schedule.name %}">Select</a>
|
||||
» {{ group.acronym }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="module">
|
||||
<h2>Requested Information</h2>
|
||||
|
||||
{% if show_request %}
|
||||
{% include "includes/sessions_request_view.html" %}
|
||||
{% endif %}
|
||||
|
||||
<div class="inline-group">
|
||||
<h2>Sessions</h2>
|
||||
|
||||
<form id="meetings-schedule-form" method="post" action="">{% csrf_token %}
|
||||
{{ formset.management_form }}
|
||||
{% for form in formset.forms %}
|
||||
<div class="inline-related{% if forloop.last %} last-related{% endif %}">
|
||||
<h3><b>Session:</b> #{{ forloop.counter }}{% if form.session_object.status.slug == 'apprw' %}<span class="message-right">Waiting for Approval</span>{% endif %}</h3>
|
||||
<table class="full-width amstable">
|
||||
<col width="200">
|
||||
{{ form }}
|
||||
</table>
|
||||
</div> <!-- inline-related -->
|
||||
{% endfor %}
|
||||
</div> <!-- inline-group -->
|
||||
|
||||
<div class="button-group">
|
||||
<ul>
|
||||
<li><button type="submit" name="submit" value="Save">Save</button></li>
|
||||
<li><button type="button" onclick="if (window.confirm('This group will be permanently removed from the agenda and scheduling tool')) { window.location='{% url "ietf.secr.meetings.views.remove_session" meeting_id=meeting.number acronym=group.acronym %}' };">Remove this group from agenda</button></li>
|
||||
<li><button type="button" onclick="window.location='{% url "ietf.secr.meetings.views.select_group" meeting_id=meeting.number schedule_name=schedule.name %}'">Back</button></li>
|
||||
</ul>
|
||||
</div> <!-- button-group -->
|
||||
|
||||
</form>
|
||||
|
||||
</div> <!-- module -->
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block footer-extras %}
|
||||
{% include "includes/meetings_footer.html" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
{% extends "base_site.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Meetings{% endblock %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script type="text/javascript" src="{% static 'secr/js/utils.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{{ block.super }}
|
||||
» <a href="../../">Meetings</a>
|
||||
» <a href="../">{{ meeting.number }}</a>
|
||||
» {{ schedule.name }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="module">
|
||||
<h2>IETF {{ meeting.number }}</h2>
|
||||
|
||||
<div class="button-group">
|
||||
<ul>
|
||||
<li><button onclick="window.location='{% url "ietf.secr.meetings.views.rooms" meeting_id=meeting.number schedule_name=schedule.name %}'">Rooms and Times</button></li>
|
||||
<li><button onclick="window.location='{% url "ietf.secr.meetings.views.select_group" meeting_id=meeting.number schedule_name=schedule.name %}'">Edit Session</button></li>
|
||||
<li><button type="button" onclick="window.location='../'">Back</button></li>
|
||||
</ul>
|
||||
</div> <!-- button-group -->
|
||||
|
||||
</div> <!-- module -->
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
{% extends "base_site.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}Meetings{% endblock %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<script type="text/javascript" src="{% static 'secr/js/utils.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{{ block.super }}
|
||||
» <a href="{% url "ietf.secr.meetings.views.main" %}">Meetings</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.view" meeting_id=meeting.number %}">{{ meeting.number }}</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.select" meeting_id=meeting.number schedule_name=schedule.name %}">{{ schedule.name }}</a>
|
||||
» Select Group
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="module">
|
||||
<h2>IETF {{ meeting.number }} - Scheduled Sessions</h2>
|
||||
|
||||
<ul id="id_scheduled_sessions">
|
||||
{% for assignment in assignments %}
|
||||
<li><a href="{% url "ietf.secr.meetings.views.session_edit" meeting_id=meeting.number schedule_name=schedule.name session_id=assignment.session.pk %}">{{ assignment.session.group.acronym }} - {{ assignment.timeslot.time|date:"D" }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
</div> <!-- module -->
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block footer-extras %}
|
||||
{% include "includes/meetings_footer.html" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -9,8 +9,6 @@
|
|||
{% block breadcrumbs %}{{ block.super }}
|
||||
» <a href="{% url "ietf.secr.meetings.views.main" %}">Meetings</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.view" meeting_id=meeting.number %}">{{ meeting.number }}</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.select" meeting_id=meeting.number schedule_name=schedule.name %}">{{ schedule.name }}</a>
|
||||
» <a href="{% url "ietf.secr.meetings.views.select_group" meeting_id=meeting.number schedule_name=schedule.name %}">Select</a>
|
||||
» {{ session.group.acronym }}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -47,8 +45,7 @@
|
|||
<div class="button-group">
|
||||
<ul>
|
||||
<li><button type="submit" name="submit" value="Save">Save</button></li>
|
||||
<li><button type="submit" name="submit" value="Cancel">Cancel Session</button></li>
|
||||
<li><button type="button" onclick="window.location='{% url "ietf.secr.meetings.views.select_group" meeting_id=meeting.number schedule_name=schedule.name %}'">Back</button></li>
|
||||
<li><button type="button" onclick="window.location='{% url "ietf.secr.meetings.views.sessions" meeting_id=meeting.number schedule_name=schedule.name %}'">Back</button></li>
|
||||
</ul>
|
||||
</div> <!-- button-group -->
|
||||
|
||||
|
|
51
ietf/secr/templates/meetings/sessions.html
Normal file
51
ietf/secr/templates/meetings/sessions.html
Normal file
|
@ -0,0 +1,51 @@
|
|||
{% extends "meetings/base_rooms_times.html" %}
|
||||
{% load bootstrap3 %}
|
||||
|
||||
{% block subsection %}
|
||||
|
||||
<div class="module role-container">
|
||||
<h2>Sessions</h2>
|
||||
|
||||
<table class="table table-condensed table-striped ipr-table tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Group</th>
|
||||
<th>Time</th>
|
||||
<th>Room</th>
|
||||
<th>Agenda Note</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for session in sessions %}
|
||||
<tr>
|
||||
<td>{{ session.group.acronym }}</td>
|
||||
<td>
|
||||
{% if session.official_timeslotassignment %}
|
||||
{{ session.official_timeslotassignment.timeslot.time|date:"l H:i"|default:"" }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if session.official_timeslotassignment %}
|
||||
{{ session.official_timeslotassignment.timeslot.location }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ session.agenda_note }}</td>
|
||||
<td>{{ session.status }}</td>
|
||||
<td><a href="{% url 'ietf.secr.meetings.views.session_edit' meeting_id=meeting.number schedule_name=schedule.name session_id=session.id %}">Edit</a></td>
|
||||
<td>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="pk" value="{{ session.pk }}">
|
||||
<input type="submit" name="cancel" value="Cancel">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div> <!-- module -->
|
||||
|
||||
{% endblock %}
|
|
@ -38,14 +38,17 @@
|
|||
<li><button onclick="window.location='{% url "ietf.secr.meetings.views.notifications" meeting_id=meeting.number %}'">Notifications</button></li>
|
||||
<li><button onclick="window.location='{% url "ietf.secr.meetings.views.blue_sheet" meeting_id=meeting.number %}'">Blue Sheets</button></li>
|
||||
<li><button onclick="window.location='{% url "ietf.meeting.views.list_agendas" num=meeting.number %}'">Agenda List</button></li>
|
||||
<li><form id="id_schedule_selector">
|
||||
<select name="forma" onchange="location = this.options[this.selectedIndex].value;">
|
||||
<option value="">Select a schedule...</option>
|
||||
{% for sched in meeting.schedule_set.all %}
|
||||
<option value="{{ sched.name }}">{{ sched.name }}{% if sched == meeting.agenda %} (official){% endif %}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</form></li>
|
||||
<li>
|
||||
<form id="id_schedule_selector">
|
||||
<select name="forma" onchange="location = this.options[this.selectedIndex].value;">
|
||||
<option value="">Select a schedule...</option>
|
||||
{% for sched in meeting.schedule_set.all %}
|
||||
<option value="{{ sched.name }}">{{ sched.name }}{% if sched == meeting.agenda %} (official){% endif %}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</form>
|
||||
</li>
|
||||
<li><button onclick="window.location='{% url "ietf.secr.meetings.views.rooms" meeting_id=meeting.number schedule_name=meeting.agenda.name %}'">Official Schedule</button></li>
|
||||
</ul>
|
||||
</div> <!-- button-group -->
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
{% if show_approve_button %}
|
||||
<li><button onclick="window.location='approve/'">Approve Third Session</button></li>
|
||||
{% endif %}
|
||||
<li><button onclick="if (window.confirm('Do you really want to cancel this session?')) { window.location='cancel/' };">Cancel this Request</button></li>
|
||||
<li><button onclick="if (window.confirm('Do you really want to cancel this session?')) { window.location='cancel/' };" {% if is_locked %} disabled{% endif %}>Cancel this Request</button></li>
|
||||
<li><button onclick="window.location='{% url "ietf.secr.sreq.views.main" %}'">Back</button></li>
|
||||
</ul>
|
||||
</div> <!-- button-group -->
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<div id="telechat-main">
|
||||
{% if date %}
|
||||
<div id="telechat-nav">
|
||||
<ul id="list-nav">
|
||||
<ul class="list-nav">
|
||||
<li><a href="{% url 'ietf.secr.telechat.views.roll_call' date=date %}">Roll Call</a></li>
|
||||
<li><a href="{% url 'ietf.secr.telechat.views.bash' date=date %}">Bash Agenda</a></li>
|
||||
<li><a href="{% url 'ietf.secr.telechat.views.minutes' date=date %}">Minute Approval</a></li>
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue