fix various issues with recent changes
- Legacy-Id: 7559
This commit is contained in:
parent
0fafe56381
commit
2ff7900326
|
@ -111,9 +111,6 @@ class MeetingRoomForm(forms.ModelForm):
|
|||
model = Room
|
||||
fields = '__all__'
|
||||
|
||||
class ExtraSessionForm(forms.Form):
|
||||
no_notify = forms.BooleanField(required=False, label="Do NOT notify this action")
|
||||
|
||||
class NewSessionForm(forms.Form):
|
||||
day = forms.ChoiceField(choices=SESSION_DAYS)
|
||||
time = TimeChoiceField()
|
||||
|
|
|
@ -1,14 +1,33 @@
|
|||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from ietf.utils import TestCase
|
||||
|
||||
from ietf.meeting.models import Meeting, Schedule
|
||||
from ietf.person.models import Person
|
||||
from ietf.group.models import Group, GroupEvent
|
||||
from ietf.meeting.models import Meeting, Schedule, Room, TimeSlot, ScheduledSession
|
||||
from ietf.utils.test_data import make_test_data
|
||||
from ietf.utils.mail import outbox
|
||||
from ietf.meeting.test_data import make_meeting_test_data
|
||||
|
||||
from pyquery import PyQuery
|
||||
from pprint import pprint
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import shutil
|
||||
|
||||
SECR_USER='secretary'
|
||||
|
||||
class MainTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.bluesheet_dir = os.path.abspath("tmp-bluesheet-dir")
|
||||
self.bluesheet_path = os.path.join(self.bluesheet_dir,'blue_sheet.rtf')
|
||||
os.mkdir(self.bluesheet_dir)
|
||||
settings.SECR_BLUE_SHEET_PATH = self.bluesheet_path
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.bluesheet_dir)
|
||||
|
||||
def test_main(self):
|
||||
"Main Test"
|
||||
url = reverse('meetings')
|
||||
|
@ -17,19 +36,161 @@ class MainTestCase(TestCase):
|
|||
|
||||
def test_view(self):
|
||||
"View Test"
|
||||
draft = make_test_data()
|
||||
meeting = Meeting.objects.all()[0]
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('meetings_view', kwargs={'meeting_id':meeting.number})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
q = PyQuery(response.content)
|
||||
self.assertEqual(len(q('#id_schedule_selector option')),2)
|
||||
|
||||
def test_add_meeting(self):
|
||||
"Add Meeting"
|
||||
url = reverse('meetings_add')
|
||||
post_data = dict(number=1,city='Seattle',date='2014-07-20',country='US',
|
||||
time_zone='America/Los_Angeles',venue_name='Hilton',
|
||||
post_data = dict(number=1,city='Toronto',date='2014-07-20',country='CA',
|
||||
time_zone='America/New_York',venue_name='Hilton',
|
||||
venue_addr='100 First Ave')
|
||||
response = self.client.post(url, post_data,follow=True,REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(Meeting.objects.count(),1)
|
||||
self.assertEqual(Schedule.objects.count(),1)
|
||||
|
||||
def test_edit_meeting(self):
|
||||
"Edit Meeting"
|
||||
Meeting.objects.create(number=1,
|
||||
type_id='ietf',
|
||||
date=datetime.datetime(2014,7,20))
|
||||
url = reverse('meetings_edit_meeting',kwargs={'meeting_id':1})
|
||||
post_data = dict(number='1',date='2014-07-20',city='Toronto')
|
||||
response = self.client.post(url, post_data,follow=True,REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
meeting = Meeting.objects.get(number=1)
|
||||
self.assertEqual(meeting.city,'Toronto')
|
||||
|
||||
def test_blue_sheets(self):
|
||||
"Test Bluesheets"
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('meetings_blue_sheet',kwargs={'meeting_id':meeting.number})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
url = reverse('meetings_blue_sheet_generate',kwargs={'meeting_id':meeting.number})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(os.path.exists(self.bluesheet_path))
|
||||
|
||||
def test_notifications(self):
|
||||
"Test Notifications"
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('meetings_notifications',kwargs={'meeting_id':42})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
q = PyQuery(response.content)
|
||||
self.assertEqual(q('#id_notification_list').html(),'ames,mars')
|
||||
|
||||
# test that only changes since last notification show up
|
||||
mars_group = Group.objects.get(acronym='mars')
|
||||
ames_group = Group.objects.get(acronym='ames')
|
||||
now = datetime.datetime.now()
|
||||
then = datetime.datetime.now()+datetime.timedelta(hours=1)
|
||||
person = Person.objects.get(name="(System)")
|
||||
GroupEvent.objects.create(group=mars_group,time=now,type='sent_notification',
|
||||
by=person,desc='sent scheduled notification for %s' % meeting)
|
||||
ss = meeting.agenda.scheduledsession_set.get(session__group=ames_group)
|
||||
ss.modified = then
|
||||
ss.save()
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
q = PyQuery(response.content)
|
||||
self.assertEqual(q('#id_notification_list').html(),'ames')
|
||||
|
||||
# test that email goes out
|
||||
mailbox_before = len(outbox)
|
||||
response = self.client.post(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(len(outbox), mailbox_before + 1)
|
||||
|
||||
def test_meetings_select(self):
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('meetings_select',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_meetings_rooms(self):
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('meetings_rooms',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
q = PyQuery(response.content)
|
||||
self.assertEqual(len(q("#id_rooms_table tr")),2)
|
||||
|
||||
# test delete
|
||||
# first unschedule sessions so we can delete
|
||||
ScheduledSession.objects.filter(schedule=meeting.agenda).delete()
|
||||
response = self.client.post(url, {
|
||||
'room-TOTAL_FORMS': q('input[name="room-TOTAL_FORMS"]').val(),
|
||||
'room-INITIAL_FORMS': q('input[name="room-INITIAL_FORMS"]').val(),
|
||||
'room-0-meeting': q('input[name="room-0-meeting"]').val(),
|
||||
'room-0-id': q('input[name="room-0-id"]').val(),
|
||||
'room-0-name': q('input[name="room-0-name"]').val(),
|
||||
'room-0-capacity': q('input[name="room-0-capacity"]').val(),
|
||||
'room-0-DELETE': 'on'
|
||||
}, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(Room.objects.filter(meeting=meeting).count(),0)
|
||||
|
||||
def test_meetings_times(self):
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('meetings_times',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_meetings_times_delete(self):
|
||||
meeting = make_meeting_test_data()
|
||||
qs = TimeSlot.objects.filter(meeting=meeting,type='session')
|
||||
before = qs.count()
|
||||
url = reverse('meetings_times_delete',kwargs={
|
||||
'meeting_id':42,
|
||||
'schedule_name':'test-agenda',
|
||||
'time':qs.first().time.strftime("%Y:%m:%d:%H:%M")
|
||||
})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
pprint(response.content)
|
||||
after = TimeSlot.objects.filter(meeting=meeting,type='session').count()
|
||||
self.assertEqual(after,before - (Room.objects.filter(meeting=meeting).count()))
|
||||
|
||||
def test_meetings_times_edit(self):
|
||||
meeting = make_meeting_test_data()
|
||||
timeslot = TimeSlot.objects.filter(meeting=meeting,type='session').first()
|
||||
url = reverse('meetings_times_edit',kwargs={
|
||||
'meeting_id':42,
|
||||
'schedule_name':'test-agenda',
|
||||
'time':timeslot.time.strftime("%Y:%m:%d:%H:%M")
|
||||
})
|
||||
response = self.client.post(url, {
|
||||
'day':'1',
|
||||
'time':'08:00',
|
||||
'duration_hours':'1',
|
||||
'duration_minutes':'0',
|
||||
'name':'Testing'
|
||||
},REMOTE_USER=SECR_USER)
|
||||
pprint(response.content)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(TimeSlot.objects.filter(meeting=meeting,name='Testing'))
|
||||
|
||||
def test_meetings_nonsession(self):
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('meetings_non_session',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_meetings_select_group(self):
|
||||
meeting = make_meeting_test_data()
|
||||
url = reverse('meetings_select_group',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})
|
||||
response = self.client.get(url, REMOTE_USER=SECR_USER)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
q = PyQuery(response.content)
|
||||
self.assertEqual(len(q("#id_scheduled_sessions")),1)
|
||||
|
||||
# def test_meetings_schedule():
|
||||
|
|
@ -93,6 +93,9 @@ def build_nonsession(meeting):
|
|||
for a new meeting, based on the last meeting
|
||||
'''
|
||||
last_meeting = get_last_meeting(meeting)
|
||||
if not last_meeting:
|
||||
return None
|
||||
|
||||
delta = meeting.date - last_meeting.date
|
||||
system = Person.objects.get(name='(system)')
|
||||
schedule = get_schedule(meeting)
|
||||
|
@ -121,8 +124,11 @@ def build_nonsession(meeting):
|
|||
|
||||
def get_last_meeting(meeting):
|
||||
last_number = int(meeting.number) - 1
|
||||
return Meeting.objects.get(number=last_number)
|
||||
|
||||
try:
|
||||
return Meeting.objects.get(number=last_number)
|
||||
except Meeting.DoesNotExist:
|
||||
return None
|
||||
|
||||
def is_combined(session,meeting,schedule=None):
|
||||
'''
|
||||
Check to see if this session is using two combined timeslots
|
||||
|
@ -204,11 +210,13 @@ def send_notifications(meeting, groups, person):
|
|||
GroupEvent.objects.create(group=group,time=now,type='sent_notification',
|
||||
by=person,desc='sent scheduled notification for %s' % meeting)
|
||||
|
||||
def sort_groups(meeting):
|
||||
def sort_groups(meeting,schedule=None):
|
||||
'''
|
||||
Similar to sreq.views.sort_groups
|
||||
Takes a Meeting object and returns a tuple scheduled_groups, unscheduled groups.
|
||||
'''
|
||||
if not schedule:
|
||||
schedule = meeting.agenda
|
||||
scheduled_groups = []
|
||||
unscheduled_groups = []
|
||||
#sessions = Session.objects.filter(meeting=meeting,status__in=('schedw','apprw','appr','sched','notmeet','canceled'))
|
||||
|
@ -216,7 +224,7 @@ def sort_groups(meeting):
|
|||
groups_with_sessions = [ s.group for s in sessions ]
|
||||
gset = set(groups_with_sessions)
|
||||
sorted_groups_with_sessions = sorted(gset, key = lambda instance: instance.acronym)
|
||||
scheduled_sessions = ScheduledSession.objects.filter(schedule=meeting.agenda,session__isnull=False)
|
||||
scheduled_sessions = ScheduledSession.objects.filter(schedule=schedule,session__isnull=False)
|
||||
groups_with_timeslots = [ x.session.group for x in scheduled_sessions ]
|
||||
for group in sorted_groups_with_sessions:
|
||||
if group in groups_with_timeslots:
|
||||
|
@ -358,15 +366,15 @@ def edit_meeting(request, meeting_id):
|
|||
|
||||
if request.method == 'POST':
|
||||
button_text = request.POST.get('submit','')
|
||||
if button_text == 'Save':
|
||||
form = MeetingModelForm(request.POST, instance=meeting)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request,'The meeting entry was changed successfully')
|
||||
return redirect('meetings_view', meeting_id=meeting_id)
|
||||
|
||||
else:
|
||||
if button_text == 'Cancel':
|
||||
return redirect('meetings_view', meeting_id=meeting_id)
|
||||
|
||||
form = MeetingModelForm(request.POST, instance=meeting)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request,'The meeting entry was changed successfully')
|
||||
return redirect('meetings_view', meeting_id=meeting_id)
|
||||
|
||||
else:
|
||||
form = MeetingModelForm(instance=meeting)
|
||||
|
||||
|
@ -559,7 +567,7 @@ def notifications(request, meeting_id):
|
|||
|
||||
return render_to_response('meetings/notifications.html', {
|
||||
'meeting': meeting,
|
||||
'groups': groups,
|
||||
'groups': sorted(groups, key=lambda a: a.acronym),
|
||||
'last_notice': last_notice },
|
||||
RequestContext(request, {}),
|
||||
)
|
||||
|
@ -671,9 +679,8 @@ def schedule(request, meeting_id, schedule_name, acronym):
|
|||
return redirect('meetings_select_group', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
|
||||
formset = NewSessionFormset(request.POST,initial=initial)
|
||||
extra_form = ExtraSessionForm(request.POST)
|
||||
|
||||
if formset.is_valid() and extra_form.is_valid():
|
||||
if formset.is_valid():
|
||||
# TODO formsets don't have has_changed until Django 1.3
|
||||
has_changed = False
|
||||
for form in formset.forms:
|
||||
|
@ -728,28 +735,15 @@ def schedule(request, meeting_id, schedule_name, acronym):
|
|||
assign(session,next_slot,meeting,schedule=schedule)
|
||||
# ---------------------------------------
|
||||
|
||||
# notify. dont send if Tutorial, BOF or indicated on form
|
||||
#notification_message = "No notification has been sent to anyone for this session."
|
||||
#if (has_changed
|
||||
# and not extra_form.cleaned_data.get('no_notify',False)
|
||||
# and group.state.slug != 'bof'
|
||||
# and get_timeslot(session,schedule=schedule)): # and the session is scheduled, else skip
|
||||
|
||||
# send_notification(request, sessions)
|
||||
# notification_message = "Notification sent."
|
||||
|
||||
if has_changed:
|
||||
messages.success(request, 'Session(s) Scheduled for %s. %s' % (group.acronym, notification_message))
|
||||
messages.success(request, 'Session(s) Scheduled for %s.' % group.acronym )
|
||||
|
||||
return redirect('meetings_select_group', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
|
||||
|
||||
else:
|
||||
formset = NewSessionFormset(initial=initial)
|
||||
extra_form = ExtraSessionForm()
|
||||
|
||||
return render_to_response('meetings/schedule.html', {
|
||||
'extra_form': extra_form,
|
||||
'group': group,
|
||||
'meeting': meeting,
|
||||
'schedule': schedule,
|
||||
|
@ -785,15 +779,15 @@ def select_group(request, meeting_id, schedule_name):
|
|||
if request.method == 'POST':
|
||||
group = request.POST.get('group',None)
|
||||
if group:
|
||||
redirect_url = reverse('meetings_schedule', kwargs={'meeting_id':meeting_id,'acronym':group})
|
||||
redirect_url = reverse('meetings_schedule', kwargs={'meeting_id':meeting_id,'acronym':group,'schedule_name':schedule_name})
|
||||
else:
|
||||
redirect_url = reverse('meetings_select_group',kwargs={'meeting_id':meeting_id})
|
||||
redirect_url = reverse('meetings_select_group',kwargs={'meeting_id':meeting_id,'schedule_name':schedule_name})
|
||||
messages.error(request, 'No group selected')
|
||||
|
||||
return HttpResponseRedirect(redirect_url)
|
||||
|
||||
# split groups into scheduled / unscheduled
|
||||
scheduled_groups, unscheduled_groups = sort_groups(meeting)
|
||||
scheduled_groups, unscheduled_groups = sort_groups(meeting,schedule)
|
||||
|
||||
# prep group form
|
||||
wgs = filter(lambda a: a.type_id in ('wg','ag') and a.state_id=='active', unscheduled_groups)
|
||||
|
@ -947,12 +941,12 @@ def times_delete(request, meeting_id, schedule_name, time):
|
|||
parts = [ int(x) for x in time.split(':') ]
|
||||
dtime = datetime.datetime(*parts)
|
||||
|
||||
qs = meeting.agenda.scheduledsession_set.filter(timeslot__time=dtime,
|
||||
session__isnull=False)
|
||||
# qs = meeting.agenda.scheduledsession_set.filter(timeslot__time=dtime,
|
||||
# session__isnull=False)
|
||||
|
||||
if qs:
|
||||
messages.error(request, 'ERROR deleting timeslot. There is one or more sessions scheduled for this timeslot.')
|
||||
return redirect('meetings_times', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
#if qs:
|
||||
# messages.error(request, 'ERROR deleting timeslot. There is one or more sessions scheduled for this timeslot.')
|
||||
# return redirect('meetings_times', meeting_id=meeting_id,schedule_name=schedule_name)
|
||||
|
||||
TimeSlot.objects.filter(meeting=meeting,time=dtime).delete()
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<form id="id_notification_form" action="." method="post">{% csrf_token %}
|
||||
<p>Send email notifications to all groups that have been scheduled since the last
|
||||
notification went out on {{ last_notice.time|date:"Y-m-d" }}:</p>
|
||||
<p>{% if not groups %}(none){% endif %}{% for group in groups %}{{ group.acronym }}{% if not forloop.last %},{% endif %}{% endfor %}<p>
|
||||
<p id="id_notification_list">{% if not groups %}(none){% endif %}{% for group in groups %}{{ group.acronym }}{% if not forloop.last %},{% endif %}{% endfor %}<p>
|
||||
<input type="submit" value="Send Now" name="submit" onclick="return window.confirm('Are you sure you want to send notifications?');">
|
||||
</form>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<form id="meetings-meta-rooms" action="" method="post">{% csrf_token %}
|
||||
{{ formset.management_form }}
|
||||
{{ formset.non_form_errors }}
|
||||
<table class="full-width">
|
||||
<table id="id_rooms_table" class="full-width">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for field in formset.forms.0.visible_fields %}
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{{ block.super }}
|
||||
» <a href="../../">Meetings</a>
|
||||
» <a href="{% url "meetings_view" meeting_id=meeting.number %}">{{ meeting }}</a>
|
||||
» <a href="{% url "meetings" %}">Meetings</a>
|
||||
» <a href="{% url "meetings_view" meeting_id=meeting.number %}">{{ meeting.number }}</a>
|
||||
» <a href="{% url "meetings_select" meeting_id=meeting.number schedule_name=schedule.name %}">{{ schedule.name }}</a>
|
||||
» <a href="{% url "meetings_select_group" meeting_id=meeting.number schedule_name=schedule.name %}">Select</a>
|
||||
» {{ group.acronym }}
|
||||
|
@ -67,11 +67,6 @@
|
|||
{% endfor %}
|
||||
</div> <!-- inline-group -->
|
||||
|
||||
<table class="full-width amstable">
|
||||
<col width="200">
|
||||
{{ extra_form }}
|
||||
</table>
|
||||
|
||||
<div class="button-group">
|
||||
<ul>
|
||||
<li><button type="submit" name="submit" value="Save">Save</button></li>
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
<div class="inline-related">
|
||||
<h2>Scheduled Sessions</h2>
|
||||
<ul>
|
||||
<ul id="id_scheduled_sessions">
|
||||
{% for group in scheduled_groups %}
|
||||
<li><a href="{% url "meetings_schedule" meeting_id=meeting.number schedule_name=schedule.name acronym=group.acronym %}">{{ group.acronym }}</a></li>
|
||||
{% endfor %}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<td>{{ item.time|date:"H:i" }} - {{ item.end_time|date:"H:i" }}</td>
|
||||
<td>{{ item.name }}</td>
|
||||
<td><a href="{% url "meetings_times_edit" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}">Edit</a></td>
|
||||
<td><a href="{% url "meetings_times_delete" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}">Delete</a></td>
|
||||
<td><a href="{% url "meetings_times_delete" meeting_id=meeting.number schedule_name=schedule.name time=item.time|date:"Y:m:d:H:i" %}" onclick="return window.confirm('Are you sure you want to delete this timeslot? Any sessions assigned to this timeslot will be unscheduled.');">Delete</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
<li><button onclick="window.location='{% url "meetings_edit_meeting" meeting_id=meeting.number %}'">Edit</button></li>
|
||||
<li><button onclick="window.location='{% url "meetings_notifications" meeting_id=meeting.number %}'">Notifications</button></li>
|
||||
<li><button onclick="window.location='{% url "meetings_blue_sheet" meeting_id=meeting.number %}'">Blue Sheets</button></li>
|
||||
<li><form id="schedule-selector">
|
||||
<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="">Select a schedule...</option>
|
||||
<option value="{{ sched.name }}">{{ sched.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
|
|
@ -490,7 +490,7 @@ tr.break td {
|
|||
border-top: 2px solid black;
|
||||
}
|
||||
|
||||
#schedule-selector {
|
||||
#id_schedule_selector {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue