[open-ils-commits] r1122 - in servres/trunk/conifer: integration syrup syrup/views templates (gfawcett)

svn at svn.open-ils.org svn at svn.open-ils.org
Mon Dec 27 19:40:53 EST 2010


Author: gfawcett
Date: 2010-12-27 19:40:52 -0500 (Mon, 27 Dec 2010)
New Revision: 1122

Modified:
   servres/trunk/conifer/integration/uwindsor.py
   servres/trunk/conifer/syrup/integration.py
   servres/trunk/conifer/syrup/views/sites.py
   servres/trunk/conifer/templates/edit_site_permissions.xhtml
Log:
site permissions: add class list by section number, or by external group code

If you provide a hook function, 'derive_group_code_from_section',
mapping section numbers onto external group/class-list codes (in the
context of a given site), then users can easily add sections to course
sites, just by providing the section number(s). If not, then the part
of the UI related to section numbers is not displayed.

Note that external group members are loaded lazily: we don't know who
belongs to an external group until they log into Syrup, and their
external memberships are updated.

Modified: servres/trunk/conifer/integration/uwindsor.py
===================================================================
--- servres/trunk/conifer/integration/uwindsor.py	2010-12-28 00:40:49 UTC (rev 1121)
+++ servres/trunk/conifer/integration/uwindsor.py	2010-12-28 00:40:52 UTC (rev 1122)
@@ -265,6 +265,24 @@
         return out
 
 
+def derive_group_code_from_section(site, section):
+    """
+    This function is used to simplify common-case permission setting
+    on course sites. It takes a site and a section number/code, and
+    returns the most likely external group code. (This function will
+    probably check the site's term and course codes, and merge those
+    with the section code, to derive the group code.) Return None if a
+    valid, unambiguous group code cannot be generated.
+    """
+    try:
+        section = int(section)
+    except:
+        return None
+
+    return '%s-%s-%s' % (site.course.code.replace('-', ''),
+                         section, 
+                         site.start_term.code)
+                         
 #--------------------------------------------------
 # proxy server integration
 

Modified: servres/trunk/conifer/syrup/integration.py
===================================================================
--- servres/trunk/conifer/syrup/integration.py	2010-12-28 00:40:49 UTC (rev 1121)
+++ servres/trunk/conifer/syrup/integration.py	2010-12-28 00:40:52 UTC (rev 1122)
@@ -132,6 +132,17 @@
     """
 
 @disable
+def derive_group_code_from_section(site, section):
+    """
+    This function is used to simplify common-case permission setting
+    on course sites. It takes a site and a section number/code, and
+    returns the most likely external group code. (This function will
+    probably check the site's term and course codes, and merge those
+    with the section code, to derive the group code.) Return None if a
+    valid, unambiguous group code cannot be generated.
+    """
+
+ at disable
 def proxify_url(url):
     """
     Given a URL, determine whether the URL needs to be passed through

Modified: servres/trunk/conifer/syrup/views/sites.py
===================================================================
--- servres/trunk/conifer/syrup/views/sites.py	2010-12-28 00:40:49 UTC (rev 1121)
+++ servres/trunk/conifer/syrup/views/sites.py	2010-12-28 00:40:52 UTC (rev 1122)
@@ -94,16 +94,36 @@
 
     choose_access = django.forms.RadioSelect(choices=choices)
 
+    show_add_section_panel = gethook('derive_group_code_from_section')
+
     if request.method != 'POST':
         return g.render('edit_site_permissions.xhtml', **locals())
     else:
         POST = request.POST
-        access = POST.get('access')
-        site.access = access
+        message = 'Changes saved.' # default
+
+        if 'action_access_level' in POST:
+            access = POST.get('access')
+            site.access = access
+
+        elif 'action_add_group' in POST:
+            section = POST.get('section', '').strip()
+            groupcode = None
+            if section:
+                groupcode = callhook('derive_group_code_from_section', 
+                                     site, section)
+            if not groupcode:
+                groupcode = POST.get('groupcode','').strip()
+            
+            if not groupcode:
+                message = 'No group code or section number provided.'
+            else:
+                group, created = models.Group.objects.get_or_create(
+                    site=site, external_id=groupcode)
+                
         site.save()
+        return g.render('edit_site_permissions.xhtml', **locals())
 
-        return HttpResponseRedirect('../../')
-
 @instructors_only
 def delete_site(request, site_id):
     site = get_object_or_404(models.Site, pk=site_id)

Modified: servres/trunk/conifer/templates/edit_site_permissions.xhtml
===================================================================
--- servres/trunk/conifer/templates/edit_site_permissions.xhtml	2010-12-28 00:40:49 UTC (rev 1121)
+++ servres/trunk/conifer/templates/edit_site_permissions.xhtml	2010-12-28 00:40:52 UTC (rev 1122)
@@ -1,8 +1,9 @@
 <?python
+from django.db.models import Count
 title = _('Site permissions')
 instructors = site.get_instructors()
 members = models.Membership.objects.select_related().filter(group__site=site).order_by('user__last_name', 'user__first_name')
-extgroups = site.group_set.filter(external_id__isnull=False)
+extgroups = site.group_set.filter(external_id__isnull=False).annotate(Count('membership')).order_by('external_id')
 ?>
 <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xi="http://www.w3.org/2001/XInclude"
@@ -14,18 +15,54 @@
   <script type="text/javascript" src="${ROOT}/static/edit_site_permissions.js"/>
   <style type="text/css">
     #access_level li { list-style-type: none; }
+	.popup { background-color: #ddd; padding: 24; margin: 0 24; }
+	#message { background-color: #fdd; padding: 12; display: inline-block; }
   </style>
 </head>
 <body>
   ${site_banner(site)}
   <h1>${title}</h1>
+  <div py:if="defined('message')" id="message">${message}</div>
   <form action="." method="POST">
-    <p>Who has permission to view resources in this site?</p>
-    <div id="access_level" style="margin-left: 12;">${Markup(choose_access.render('access', site.access, {'id':'id_access'}, []))}</div>
-    <p><input type="submit" name="action_access_level" value="Change access level"/>
-    ${go_back_link()}</p>
+	<div>
+	  <h2>Security level</h2>
+	  <div>Who has permission to view resources in this site?</div>
+	  <div id="access_level" style="margin: 8;">${Markup(choose_access.render('access', site.access, {'id':'id_access'}, []))}</div>
+	  <p><input type="submit" name="action_access_level" value="Change security level"/>
+	  ${go_back_link()}</p>
+	</div>
 
-    <h2>Current Membership</h2>
+	<div>
+      <h2>Class lists and groups</h2>
+	  <div py:if="not extgroups">No external lists are currently associated.</div>
+
+	  <table class="pagetable" py:if="extgroups">
+		<thead>
+		  <tr><th>Class/group code</th><th>Known members</th></tr>
+		</thead>
+		<tbody>
+		  <tr py:for="eg in extgroups">
+			<td>${eg.external_id}</td>
+			<td>${eg.membership__count}</td>
+		  </tr>
+		</tbody>
+	  </table>
+	  <div>
+		<p><input type="button" value="Add external group" onclick="$('#addExternalGroupPopup').fadeIn();"/></p>
+		<div class="popup" id="addExternalGroupPopup" style="display: none;">
+		  <li py:if="show_add_section_panel">
+			Add the class list for ${site.course.code}, section <input name="section" style="width: 2em;"/>, ${site.start_term.name}
+		  </li>
+		  <li>
+			Add a class list or group by its group code: <input name="groupcode" style="width: 15em;"/>
+		  </li>
+		  <p><input type="submit" name="action_add_group" value="Add class list or group"/></p>
+		</div>
+	  </div>
+	  
+    </div>
+    <div>
+    <h2>Current membership</h2>
     <table class="pagetable" style="width: 100%;">
       <thead>
 	<tr><th>Name</th><th>Role</th><th>User ID</th><th>Group</th></tr>
@@ -38,39 +75,7 @@
 	<td>${member.group.external_id or '(internal)'}</td>
       </tr>
     </table>
-    <div py:if="extgroups">
-      <h2>External Groups</h2>
-      <p py:for="eg in extgroups">${eg.external_id}</p>
-    </div>
-
-    <!-- <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',_('Instructor')), (u'PROXY', _('Proxy instructor'))]) -->
-    <!-- 			    .render('instructor_role_%d' % mbr.id, mbr.role))"/> -->
-    <!--   <tr py:for="mbr in instructors"> -->
-    <!-- 	<td>${mbr.user.get_full_name() or ''} <code>(${mbr.user.username})</code></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>
   </form>
   <div class="gap"/>
 </body>



More information about the open-ils-commits mailing list