[open-ils-commits] r148 - in servres/trunk/conifer: . static syrup templates (gfawcett)

svn at svn.open-ils.org svn at svn.open-ils.org
Sun Mar 8 15:08:35 EDT 2009


Author: gfawcett
Date: 2009-03-08 15:08:31 -0400 (Sun, 08 Mar 2009)
New Revision: 148

Added:
   servres/trunk/conifer/static/edit_course_permissions.js
Modified:
   servres/trunk/conifer/genshi_namespace.py
   servres/trunk/conifer/static/main.css
   servres/trunk/conifer/syrup/views.py
   servres/trunk/conifer/templates/add_new_course.xhtml
   servres/trunk/conifer/templates/edit_course_permissions.xhtml
Log:
better edit-course-permissions screen, separated from edit-course-details.

Still no support for course-sections; coming soon.


Modified: servres/trunk/conifer/genshi_namespace.py
===================================================================
--- servres/trunk/conifer/genshi_namespace.py	2009-03-08 17:11:14 UTC (rev 147)
+++ servres/trunk/conifer/genshi_namespace.py	2009-03-08 19:08:31 UTC (rev 148)
@@ -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=''):

Added: servres/trunk/conifer/static/edit_course_permissions.js
===================================================================
--- servres/trunk/conifer/static/edit_course_permissions.js	                        (rev 0)
+++ servres/trunk/conifer/static/edit_course_permissions.js	2009-03-08 19:08:31 UTC (rev 148)
@@ -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

Modified: servres/trunk/conifer/static/main.css
===================================================================
--- servres/trunk/conifer/static/main.css	2009-03-08 17:11:14 UTC (rev 147)
+++ servres/trunk/conifer/static/main.css	2009-03-08 19:08:31 UTC (rev 148)
@@ -49,10 +49,15 @@
     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 @@
     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; }

Modified: servres/trunk/conifer/syrup/views.py
===================================================================
--- servres/trunk/conifer/syrup/views.py	2009-03-08 17:11:14 UTC (rev 147)
+++ servres/trunk/conifer/syrup/views.py	2009-03-08 19:08:31 UTC (rev 148)
@@ -9,6 +9,7 @@
 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 @@
 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,15 +147,7 @@
         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)
 COURSE_CODE_LOOKUP_TITLE = bool(models.course_codes.course_code_lookup_title)
@@ -217,14 +210,73 @@
 
 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.

Modified: servres/trunk/conifer/templates/add_new_course.xhtml
===================================================================
--- servres/trunk/conifer/templates/add_new_course.xhtml	2009-03-08 17:11:14 UTC (rev 147)
+++ servres/trunk/conifer/templates/add_new_course.xhtml	2009-03-08 19:08:31 UTC (rev 148)
@@ -8,15 +8,15 @@
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:py="http://genshi.edgewall.org/">
 <xi:include href="master.xhtml"/>
+<xi:include href="components/course.xhtml"/>
 <head>
   <title>${title}</title>
   <script type="text/javascript" src="/static/add_new_course.js"/>
 </head>
 <body>
+  <div py:if="instance.id">${course_banner(instance)}</div>
   <h1>${title}</h1>
-  <ul py:for="fld in form" py:if="fld.errors">
-    <li py:for="err in fld.errors">${fld.name}: ${err}</li>
-  </ul>
+  <p py:if="instance.id"><a href="permission/">Edit course permissions</a> &bull; <a href="${instance.course_url()}">Return to course page</a></p>
   <form action="." method="POST">
     <tr py:def="field_row(field, example=None)">
       <th>${field.label}</th>
@@ -28,8 +28,7 @@
       </td>
       <td class="example" py:if="example">e.g., ${example}</td>
     </tr>
-  <fieldset>
-    <legend>General description</legend>
+    <h2>General description</h2>
     <table class="formtable">
     ${field_row(form.code, example)}
     ${field_row(form.title)}
@@ -37,12 +36,6 @@
     ${field_row(form.department)}
     <!-- <tr><th>Department</th><td>${Markup(form.department)} ${errorlist(form.department)}</td></tr> -->
   </table>
-  </fieldset>
-  <fieldset>
-    <legend>Access controls</legend>
-    <p>This site will be available to:</p>
-    ${Markup(form.access)}
-  </fieldset>
   <p><input type="submit" value="Continue"/></p>
   </form>
 

Modified: servres/trunk/conifer/templates/edit_course_permissions.xhtml
===================================================================
--- servres/trunk/conifer/templates/edit_course_permissions.xhtml	2009-03-08 17:11:14 UTC (rev 147)
+++ servres/trunk/conifer/templates/edit_course_permissions.xhtml	2009-03-08 19:08:31 UTC (rev 148)
@@ -1,27 +1,60 @@
 <?python
 title = _('Edit course permissions')
+instructors = [m for m in models.Member.objects.filter(course=course) if m.role in ('PROXY', 'INSTR')]
 ?>
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:py="http://genshi.edgewall.org/">
 <xi:include href="master.xhtml"/>
+  <xi:include href="components/course.xhtml"/>
 <head>
   <title>${title}</title>
+  <script type="text/javascript" src="/static/edit_course_permissions.js"/>
 </head>
 <body>
+  ${course_banner(course)}
   <h1>${title}</h1>
-  <h2>Add Co-Instructors and Proxies</h2>
-  <p>blah blah...</p>    
-  <div py:choose="course.access">
-    <div py:when="'INVIT'">
-      <h2>Course Invitation Code</h2>
-      <p style="font-size: larger;">Your Course Invitation Code is: <strong>${course.passkey}</strong></p>
-      <form action="." method="POST">
-	<p>
-	  <input type="hidden" name="action" value="change_code"/>
-	  <input type="submit" value="Select a new code (this will invalidate the old code!)"/>
-	</p>
-	</form>
+  <p><a href="../">Edit course details</a> &bull; <a href="${course.course_url()}">Return to course page</a></p>
+  <form action="." method="POST">
+    <h2>Instructor Access</h2>
+    <div py:if="defined('instructor_error')" class="errors">${instructor_error}</div>
+    <table class="pagetable">
+      <thead>
+	<tr><th>Person</th><th>Role</th><th>Remove?</th></tr>
+      </thead>
+      <tbody>
+	<select py:def="select_role(mbr)" 
+		py:replace="Markup(django.forms.Select(choices=
+			    [(u'INSTR',_(u'Instructor')), (u'PROXY', _(u'Proxy instructor'))])
+			    .render('instructor_role_%d' % mbr.id, mbr.role))"/>
+      <tr py:for="mbr in instructors">
+	<td>${mbr.user.get_full_name() or mbr.user}</td>
+	<td>${select_role(mbr)}</td>
+	<td><input type="checkbox" name="instructor_remove_${mbr.id}"/></td>
+      </tr>
+      <tr style="vertical-align: bottom;">
+	<td><p>Username of the new instructor.</p><input type="text" name="new_instructor_name"/></td>
+	<td><select name="new_instructor_role">
+	  <option value="INSTR">Instructor</option>
+	  <option value="PROXY">Proxy instructor</option>
+	  </select>
+	</td>
+	<td/>
+      </tr>
+      </tbody>
+    </table>
+    <p>	  <input type="submit" name="action_save_instructor" value="Save changes to instructors"/></p>
+    <div class="gap"/>
+    <h2>Student Access</h2>
+    <p>Who will have student-level access to this site?
+    <span style="margin-left: 12;"/>${Markup(choose_access.render('access', course.access, {'id':'id_access'}, []))}</p>
+    <div id="INVIT_panel" class="specific">
+      <h3>Course Invitation Code</h3>
+      <p style="font-size: larger;">Your Course Invitation Code is: <strong>${course.passkey}</strong>
+      <span style="margin-left: 16;">
+	  <input type="submit" name="action_change_code" value="Select a new code"/>
+      </span>
+      </p>
       <p>This invitation code will enable your students to join this
       course site. Share it only with your students: anyone who has
       the code can join your site.</p>
@@ -29,10 +62,19 @@
       students who have already joined, but will prevent new students
       from joining with the old code.</p>
     </div>
-    <div py:when="'STUDT'">
-      <h2>Course section numbers</h2>
+    <div id="STUDT_panel" class="specific">
+      <h3>Course section numbers</h3>
+      <table>
+	<tr py:for="x in range(3)"><td><input type="text"/></td></tr>
+      </table>
     </div>
-  </div>
+    <p><input type="submit" name="action_save_student" value="Save changes to student access"/></p>
+
+    <div class="gap"/>
+    <h2>Class List</h2>
+    <p>The following users have student-level access in this course site.</p>
+
+  </form>
   <div class="gap"/>
 </body>
 </html>



More information about the open-ils-commits mailing list