update course people page for course role engine

include separate sections in each column for
custom student, teacher, and ta roles

test plan:
 * create custom roles
 * enroll users in a course using the new roles
 (note: this will be difficult until the ui for
 enrolling custom roles is ready)
 * confirm that the "People" page shows correctly
 (including sections)

closes #CNVS-1167 ( also #CNVS-2244 )

Change-Id: I73fcf82e407c6af00f6f8f7a8c30141adb704227
Reviewed-on: https://gerrit.instructure.com/16058
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jeremy Stanley <jeremy@instructure.com>
QA-Review: Adam Phillipps <adam@instructure.com>
This commit is contained in:
James Williams 2012-12-11 10:44:49 -07:00
parent 6fab11cc82
commit 065e9d7929
7 changed files with 146 additions and 54 deletions

View File

@ -22,7 +22,8 @@ require [
'compiled/collections/UserCollection'
'compiled/collections/SectionCollection'
'compiled/views/courses/RosterView'
], ($, _, UserCollection, SectionCollection, RosterView) ->
'jst/courses/Roster'
], ($, _, UserCollection, SectionCollection, RosterView, roster) ->
# Load environment
course = ENV.context_asset_string.split('_')[1]
@ -31,36 +32,29 @@ require [
include: ['avatar_url', 'enrollments', 'email']
per_page: 50
# Cache elements
$studentList = $('.student_roster .user_list')
$teacherList = $('.teacher_roster .user_list')
sections = new SectionCollection(ENV.SECTIONS)
columns =
students: $('.roster .student_roster')
teachers: $('.roster .teacher_roster')
# Create views
sections = new SectionCollection(ENV.SECTIONS)
students = new UserCollection
teachers = new UserCollection
for roster_data in ENV.COURSE_ROSTERS
users = new UserCollection
users.url = url
users.sections = sections
users.roles = roster_data['roles']
_.each [students, teachers], (c) ->
c.url = url
c.sections = sections
usersOptions = add: false, data: _.extend({}, fetchOptions, enrollment_role: roster_data['roles'])
studentOptions = add: false, data: _.extend({}, fetchOptions, enrollment_type: 'student')
teacherOptions = add: false, data: _.extend({}, fetchOptions, enrollment_type: ['teacher', 'ta'])
column = columns[roster_data['column']]
html = roster
title: roster_data['title']
column.append(html)
list = column.find('.user_list').last()
studentView = new RosterView
collection: students
el: $studentList
fetchOptions: studentOptions
teacherView = new RosterView
collection: teachers
el: $teacherList
fetchOptions: teacherOptions
# Add events
students.on('reset', studentView.render, studentView)
teachers.on('reset', teacherView.render, teacherView)
# Fetch roster
studentView.$el.disableWhileLoading(students.fetch(studentOptions))
teacherView.$el.disableWhileLoading(teachers.fetch(teacherOptions))
usersView = new RosterView
collection: users
el: list
fetchOptions: usersOptions
users.on('reset', usersView.render, usersView)
usersView.$el.disableWhileLoading(users.fetch(usersOptions))

View File

@ -83,7 +83,11 @@ define [
#
# Return an array of section names.
getSections: (user) ->
sections = _.map user.get('enrollments'), (enrollment) =>
enrollments = _.filter(user.get('enrollments'), ((enrollment) ->
_.contains(@roles, enrollment.role))
, @collection)
sections = _.map enrollments, (enrollment) =>
@collection.sections.find (section) -> enrollment.course_section_id == section.id
_.uniq(_.map(sections, (section) -> section.get('name')))

View File

@ -304,12 +304,32 @@ class ContextController < ApplicationController
if @context.is_a?(Course)
sections = @context.course_sections(:select => 'id, name')
js_env :SECTIONS => sections.map { |s| { :id => s.id, :name => s.name } }
all_roles = Role.custom_roles_and_counts_for_course(@context, @current_user)
header_rosters = [
{:title => t('roster.students', 'Students'), :roles => ['StudentEnrollment'], :column => 'students'},
{:title => t('roster.teachers', 'Teachers'), :roles => ['TeacherEnrollment'], :column => 'teachers'},
{:title => t('roster.tas', 'TAs'), :roles => ['TaEnrollment'], :column => 'teachers'}
]
@display_rosters = []
header_rosters.each do |hr|
base_roles = all_roles.select{|r| hr[:roles].include?(r[:base_role_name])}
@display_rosters << hr if base_roles.find{|br| br[:count] && br[:count] > 0}.present?
base_roles.each do |br|
br[:custom_roles].select{|cr| cr[:count] && cr[:count] > 0}.each do |cr|
@display_rosters << {:title => cr[:label], :roles => [cr[:name]], :column => hr[:column]}
end
end
end
elsif @context.is_a?(Group)
@users = @context.participating_users.order_by_sortable_name.uniq
@primary_users = { t('roster.group_members', 'Group Members') => @users }
if course = @context.context.try(:is_a?, Course) && @context.context
@secondary_users = { t('roster.teachers', 'Teachers & TAs') => course.instructors.order_by_sortable_name.uniq }
@secondary_users = { t('roster.teachers_and_tas', 'Teachers & TAs') => course.instructors.order_by_sortable_name.uniq }
end
end

View File

@ -4,7 +4,7 @@
min-width: 515px;
overflow: hidden;
.users-wrapper {
.users-column-wrapper {
float: left;
margin-right: 2%;
width: 47%;

View File

@ -10,23 +10,20 @@
<% if @context.is_a?(Course) %>
<div class="roster">
<div class="users-wrapper student_roster">
<h2 class="h3"><%= t('roster.students', 'Students') %></h2>
<ul class="user_list student_list">
<!-- This list is populated w/ JavaScript -->
</ul>
<div class="users-column-wrapper student_roster">
</div>
<div class="users-wrapper teacher_roster">
<h2 class="h3"><%= t('roster.teachers', 'Teachers & TAs') %></h2>
<ul class="user_list teachers_list">
<!-- This list is populated w/ JavaScript -->
</ul>
<div class="users-column-wrapper teacher_roster">
</div>
</div>
<% jammit_css :roster %>
<% js_bundle :roster %>
<% if @display_rosters.any? %>
<% jammit_css :roster %>
<% js_env :COURSE_ROSTERS => @display_rosters %>
<% js_bundle :roster %>
<% else %>
<%= t('roster.empty', 'No one is currently enrolled in this course.') %>
<% end %>
<% else %>
<% content_for :stylesheets do %>
<style>

View File

@ -0,0 +1,5 @@
<div class="users-wrapper">
<h2 class="h3">{{title}}</h2>
<ul class="user_list">
</ul>
</div>

View File

@ -122,27 +122,69 @@ describe "courses" do
course_with_teacher_logged_in
# Setup the course with > 50 users (to test scrolling)
100.times do |n|
@course.enroll_student(user).accept!
60.times do |n|
@course.enroll_student(user)
end
@course.enroll_user(user, 'TaEnrollment')
# Test that the page loads properly the first time.
get "/courses/#{@course.id}/users"
wait_for_ajaximations
ff('.ui-state-error').length.should == 0
ff('.student_roster .user').length.should == 50
ff('.teacher_roster .user').length.should == 1
ff('.teacher_roster .user').length.should == 2
ff('.teacher_roster .user_list').length.should == 2
# Test the infinite scroll.
driver.execute_script <<-END
var $wrapper = $('.student_roster .fill_height_div'),
$list = $('.student_list'),
scroll = $list.height() - $wrapper.height();
$wrapper.scrollTo(scroll);
$list = $('.student_roster .users-wrapper:first-child .user_list'),
$list[0].scrollTop = $list[0].scrollHeight - $list.height();
END
wait_for_ajaximations
ff('.student_roster li').length.should == 100
ff('.student_roster .user').length.should == 60
end
it "should include separate course roles sections on users page" do
course_with_teacher_logged_in
@course.enroll_user(user, 'TaEnrollment')
@course.enroll_user(user, 'StudentEnrollment')
roles = [
['Student', 51, '.student_roster .users-wrapper:nth-child(2)'],
['Teacher', 52, '.teacher_roster .users-wrapper:nth-child(2)'],
['Ta', 53, '.teacher_roster .users-wrapper:nth-child(4)']
]
roles.each do |type, num, css|
role = @course.account.roles.build :name => "Custom#{type}"
role.base_role_type = "#{type}Enrollment"
role.save!
num.times do |n|
@course.enroll_user(user, "#{type}Enrollment", :role_name => role.name)
end
end
# Test that the page loads properly the first time.
get "/courses/#{@course.id}/users"
wait_for_ajaximations
ff('.ui-state-error').length.should == 0
roles.each do |type, num, css|
ff("#{css} h2").first.text.should == "Custom#{type}"
ff("#{css} .user").length.should == 50
# Test the infinite scroll.
driver.execute_script <<-END
$list = $('#{css} .user_list'),
$list[0].scrollTop = $list[0].scrollHeight - $list.height();
END
wait_for_ajaximations
ff("#{css} .user").length.should == num
end
end
it "should only show users that a user has permissions to view" do
@ -183,6 +225,36 @@ describe "courses" do
sections = ff('.student_roster .section')
sections.map(&:text).sort.should == %w{One One Two}
end
it "should display users section name properly when separated by custom roles" do
course_with_teacher_logged_in(:active_all => true)
user1 = user
section1 = @course.course_sections.create!(:name => 'One')
section2 = @course.course_sections.create!(:name => 'Two')
role1 = @course.account.roles.build :name => "CustomStudent1"
role1.base_role_type = "StudentEnrollment"
role1.save!
role2 = @course.account.roles.build :name => "CustomStudent2"
role2.base_role_type = "StudentEnrollment"
role2.save!
@course.enroll_user(user1, "StudentEnrollment", :section => section1, :role_name => role1.name).accept!
@course.enroll_user(user1, "StudentEnrollment", :section => section2, :role_name => role2.name, :allow_multiple_enrollments => true).accept!
roles_to_sections = {'CustomStudent1' => 'One', 'CustomStudent2' => 'Two'}
get "/courses/#{@course.id}/users"
wait_for_ajaximations
role_wrappers = ff('.student_roster .users-wrapper')
role_wrappers.each do |rw|
role_name = ff('.h3', rw).first.text
sections = ff('.section', rw)
sections.count.should == 1
roles_to_sections[role_name].should == sections.first.text
end
end
end
context "course as a student" do