From 6a0bfdf6dbb89ba975ed352bcedcf8f2ac3aaae2 Mon Sep 17 00:00:00 2001 From: gfawcett Date: Sun, 8 Mar 2009 19:08:31 +0000 Subject: [PATCH] better edit-course-permissions screen, separated from edit-course-details. Still no support for course-sections; coming soon. git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@148 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- conifer/genshi_namespace.py | 1 + conifer/static/edit_course_permissions.js | 12 +++++ conifer/static/main.css | 11 +++- conifer/syrup/views.py | 72 +++++++++++++++++++++---- conifer/templates/add_new_course.xhtml | 15 ++---- conifer/templates/edit_course_permissions.xhtml | 72 +++++++++++++++++++------ 6 files changed, 146 insertions(+), 37 deletions(-) create mode 100644 conifer/static/edit_course_permissions.js diff --git a/conifer/genshi_namespace.py b/conifer/genshi_namespace.py index 1022c05..bb003e5 100644 --- a/conifer/genshi_namespace.py +++ b/conifer/genshi_namespace.py @@ -5,6 +5,7 @@ from itertools import cycle from conifer.syrup import models +import django.forms # this probably ought to be a method on User, or another model class. def instructor_url(instructor, suffix=''): diff --git a/conifer/static/edit_course_permissions.js b/conifer/static/edit_course_permissions.js new file mode 100644 index 0000000..92bd861 --- /dev/null +++ b/conifer/static/edit_course_permissions.js @@ -0,0 +1,12 @@ +function do_init() { + show_specific_only(); + $('#id_access').change(show_specific_only); +} + +function show_specific_only() { + $('.specific').hide(); + var cur = $('#id_access').val(); + $('#' + cur + '_panel').fadeIn(); +} + +$(do_init); \ No newline at end of file diff --git a/conifer/static/main.css b/conifer/static/main.css index 0699b7f..7560fec 100644 --- a/conifer/static/main.css +++ b/conifer/static/main.css @@ -49,10 +49,15 @@ min-height: 300; border-bottom: white 10px solid; } +/* heading sizes and colours. */ + h1 { font-size: 150%; } h2 { font-size: 135%; } -h1, h2, h3, h4 { color: navy; } +h3 { font-size: 120%; } +h1 { color: navy; } +h2 { color: #066; } +h3, h4 { color: darkgreen; } h1 a, h2 a { color: navy; } a { color: blue; text-decoration: none; } @@ -209,3 +214,7 @@ p.todo, div.todo { background-color: #fdd; padding: 6; margin: 12; border-left: font-weight: normal; } +.gap { height: 24; } + +/* panels that appear when specific OPTIONs or radio-buttons are selected. */ +.specific { padding: 8; margin: 0 16; background-color: #eef; } diff --git a/conifer/syrup/views.py b/conifer/syrup/views.py index cb9693e..7f2da57 100644 --- a/conifer/syrup/views.py +++ b/conifer/syrup/views.py @@ -9,6 +9,7 @@ import re from conifer.syrup import models from django.contrib.auth.models import User from django.db.models import Q +import django.forms from datetime import datetime from generics import * from gettext import gettext as _ # fixme, is this the right function to import? @@ -136,7 +137,7 @@ def course_search(request, course_id): class NewCourseForm(ModelForm): class Meta: model = models.Course - exclude = ('passkey',) + exclude = ('passkey','access') def clean_code(self): v = (self.cleaned_data.get('code') or '').strip() @@ -146,14 +147,6 @@ class NewCourseForm(ModelForm): else: raise ValidationError, _('invalid course code') -# I want different choice labels on the access screen than are given -# in the model. -NewCourseForm.base_fields['access'].widget.choices = [ - (u'CLOSE', _(u'For now, just myself and designated colleagues')), - (u'STUDT', _(u'Students in my course (I will provide section numbers)')), - (u'INVIT', _(u'Students in my course (I will share an Invitation Code with them)')), - (u'LOGIN', _(u'All Reserves patrons'))] - # hack the new-course form if we have course-code lookup COURSE_CODE_LIST = bool(models.course_codes.course_code_list) @@ -217,14 +210,73 @@ def add_new_course_ajax_title(request): def edit_course_permissions(request, course_id): course = get_object_or_404(models.Course, pk=course_id) + choose_access = django.forms.Select(choices=[ + (u'CLOSE', _(u'No students: this site is closed.')), + (u'STUDT', _(u'Students in my course -- I will provide section numbers')), + (u'INVIT', _(u'Students in my course -- I will share an Invitation Code with them')), + (u'LOGIN', _(u'All Reserves patrons'))]) if request.method != 'POST': return g.render('edit_course_permissions.xhtml', **locals()) else: - if request.POST.get('action') == 'change_code': + POST = request.POST + + if 'action_change_code' in POST: + # update invitation code ------------------------------------- course.generate_new_passkey() + course.access = u'INVIT' course.save() return HttpResponseRedirect('.') + elif 'action_save_instructor' in POST: + # update instructor details ---------------------------------- + iname = POST.get('new_instructor_name','').strip() + irole = POST.get('new_instructor_role') + + def get_record_for(username): + instr = models.maybe_initialize_user(iname) + if instr: + try: + return models.Member.objects.get(user=instr, course=course) + except models.Member.DoesNotExist: + return models.Member.objects.create(user=instr, course=course) + + # add a new instructor + if iname: + instr = get_record_for(iname) + if instr: # else? should have an error. + instr.role = irole + instr.save() + else: + instructor_error = 'No such user: %s' % iname + return g.render('edit_course_permissions.xhtml', **locals()) + + + # removing and changing roles of instructors + to_change_role = [(int(name.rsplit('_', 1)[-1]), POST[name]) \ + for name in POST if name.startswith('instructor_role_')] + to_remove = [int(name.rsplit('_', 1)[-1]) \ + for name in POST if name.startswith('instructor_remove_')] + for instr_id, newrole in to_change_role: + if not instr_id in to_remove: + instr = models.Member.objects.get(pk=instr_id, course=course) + instr.role = newrole + instr.save() + for instr_id in to_remove: + # todo, should warn if deleting yourself! + instr = models.Member.objects.get(pk=instr_id, course=course) + instr.delete() + # todo, should have some error-reporting. + return HttpResponseRedirect('.') + + elif 'action_save_student' in POST: + # update student details ------------------------------------ + access = POST.get('access') + course.access = access + course.save() + if course.access == u'STUDT': + raise NotImplementedError, 'No course sections yet! Coming soon.' + return HttpResponseRedirect('.') + #------------------------------------------------------------ @login_required # must be, to avoid/audit brute force attacks. diff --git a/conifer/templates/add_new_course.xhtml b/conifer/templates/add_new_course.xhtml index bf6bf7d..19d83de 100644 --- a/conifer/templates/add_new_course.xhtml +++ b/conifer/templates/add_new_course.xhtml @@ -8,15 +8,15 @@ else: xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:py="http://genshi.edgewall.org/"> + ${title}