avatars in gradebook2

Add a small user avatar icon to the left of each student's
name in the gradebook.

test plan:
- enable avatars for the account
- load a course gradebook
- make sure avatars appear correctly

- disable avatars for the account
- load a course gradebook
- make sure no avatars appear

Change-Id: Ibecbe25936979c115dcaa5af4f454320128bbd1c
Reviewed-on: https://gerrit.instructure.com/9397
Reviewed-by: Ryan Shaw <ryan@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
This commit is contained in:
Brian Whitmer 2012-02-03 23:59:20 -07:00
parent c0334ed148
commit 0f32c1d34b
9 changed files with 42 additions and 9 deletions

View File

@ -16,6 +16,7 @@ define [
'jst/gradebook2/column_header'
'jst/gradebook2/group_total_cell'
'jst/gradebook2/row_student_name'
'jst/_avatar' #needed by row_student_name
'jquery.ajaxJSON'
'jquery.instructure_date_and_time'
'jquery.instructure_jquery_patches'
@ -108,8 +109,9 @@ define [
if @sections_enabled
sectionNames = $.toSentence((@sections[sectionId].name for sectionId in student.sections).sort())
student.display_name = rowStudentNameTemplate
studentName: student.name
studentGradesUrl: student.enrollment.grades.html_url
avatar_image_url: student.avatar_url
display_name: student.name
url: student.enrollment.grades.html_url
sectionNames: sectionNames
# fill in dummy submissions, so there's something there even if the
@ -513,6 +515,8 @@ define [
$widthTester = $('<span style="padding:10px" />').appendTo('#content')
testWidth = (text, minWidth) -> Math.max($widthTester.text(text).outerWidth(), minWidth)
# I would like to make this width a little larger, but there's a dependency somewhere else that
# I can't find and if I change it, the layout gets messed up.
@parentColumns = [{
id: 'student'
name: I18n.t 'student_name', 'Student Name'

View File

@ -211,6 +211,7 @@ class CoursesController < ApplicationController
# Returns the list of sections for this course.
#
# @argument include[] [optional, "students"] Associations to include with the group.
# @argument include[] [optional, "avatar_url"] Include the avatar URLs for students returned.
#
# @response_field id The unique identifier for the course section.
# @response_field name The name of the section.
@ -237,6 +238,7 @@ class CoursesController < ApplicationController
if authorized_action(@context, @current_user, :read_roster)
includes = Array(params[:include])
include_students = includes.include?('students')
include_avatar_urls = includes.include?('avatar_url') || nil
result = @context.active_course_sections.map do |section|
res = section.as_json(:include_root => false,
@ -250,7 +252,7 @@ class CoursesController < ApplicationController
proxy = proxy.scoped(:include => :user)
end
res['students'] = proxy.all(:conditions => "type = 'StudentEnrollment'").
map { |e| user_json(e.user, @current_user, session) }
map { |e| user_json(e.user, @current_user, session, include_avatar_urls && ['avatar_url']) }
end
res
end
@ -482,7 +484,7 @@ class CoursesController < ApplicationController
enrollment = @context_enrollment if @context_enrollment && @context_enrollment.pending? && (@context_enrollment.uuid == params[:invitation] || params[:invitation].blank?)
# Overwrite with the session enrollment, if one exists, and it's different than the current user's
enrollment = @context.enrollments.find_by_uuid_and_workflow_state(session[:enrollment_uuid], "invited") if session[:enrollment_uuid] && enrollment.try(:uuid) != session[:enrollment_uuid] && params[:invitation].blank? && session[:enrollment_uuid_course_id] == @context.id
# Look for enrollments to matching temporary users
# Look for enrollments to matching temporary users
enrollment ||= @current_user.temporary_invitations.find { |i| i.course_id == @context.id } if @current_user
# Look up the explicitly provided invitation
enrollment ||= @context.enrollments.find(:first, :conditions => ["uuid=? AND workflow_state IN ('invited', 'rejected')", params[:invitation]]) unless params[:invitation].blank?

View File

@ -137,7 +137,8 @@ class EnrollmentsApiController < ApplicationController
enrollments = Api.paginate(
enrollments,
self, send("api_v1_#{endpoint_scope}_enrollments_path"))
render :json => enrollments.map { |e| enrollment_json(e, @current_user, session, [:user]) }
includes = [:user] + Array(params[:include])
render :json => enrollments.map { |e| enrollment_json(e, @current_user, session, includes) }
end
# @API

View File

@ -9,7 +9,7 @@ class Gradebook2Controller < ApplicationController
:chunk_size => Setting.get_cached('gradebook2.submissions_chunk_size', '35').to_i,
:assignment_groups_url => api_v1_course_assignment_groups_url(@context, :include => [:assignments]),
:sections_url => api_v1_course_sections_url(@context),
:students_url => api_v1_course_enrollments_url(@context, :type => ['StudentEnrollment'], :per_page => 100),
:students_url => api_v1_course_enrollments_url(@context, :include => [:avatar_url], :type => ['StudentEnrollment'], :per_page => 100),
:submissions_url => api_v1_course_student_submissions_url(@context, :grouped => '1'),
:change_grade_url => api_v1_course_assignment_submission_url(@context, ":assignment", ":submission"),
:context_url => named_context_url(@context, :context_url),

View File

@ -36,6 +36,12 @@ $cell_height: 33px
.student-name
color: #1b7eda
text-shadow: #fbf8f8 0 0 1px
.avatar
float: left
width: 34px
img
max-width: 30px
height: 30px
.student-section
font-size: 10px
color: #aaa

View File

@ -1,3 +1,3 @@
{{#if avatar_image_url}}
<a {{#if url}} href="{{url}}" {{/if}} class="avatar"><img src="{{avatar_image_url}}" alt="{{display_name}}"></a>
<a {{#if url}} href="{{url}}" {{/if}} class="avatar" {{#if display_name}} title="{{display_name}}" {{/if}}><img src="{{avatar_image_url}}" alt="{{display_name}}"></a>
{{/if}}

View File

@ -1,4 +1,5 @@
<div class='student-name'><a class='student-grades-link' href="{{studentGradesUrl}}">{{{studentName}}}</a></div>
{{>avatar}}
<div class='student-name'><a class='student-grades-link' href="{{url}}">{{{display_name}}}</a></div>
{{#if sectionNames}}
<div class='student-section'>{{{sectionNames}}}</div>
{{/if}}

View File

@ -14,7 +14,8 @@ module Api::V1::Enrollment
}
end
json[:html_url] = course_user_url(enrollment.course_id, enrollment.user_id)
json[:user] = user_json(enrollment.user, user, session) if includes.include?(:user)
user_includes = includes.include?('avatar_url') ? ['avatar_url'] : []
json[:user] = user_json(enrollment.user, user, session, user_includes) if includes.include?(:user)
end
end
end

View File

@ -299,6 +299,24 @@ describe "gradebook2" do
dom_names = driver.find_elements(:css, '.student-name').map(&:text)
dom_names.should == [STUDENT_NAME_1, STUDENT_NAME_2]
end
it "should not show student avatars until they are enabled" do
get "/courses/#{@course.id}/gradebook2"
wait_for_ajaximations
driver.find_elements(:css, '.student-name').length.should == 2
driver.find_elements(:css, '.avatar img').length.should == 0
@account = Account.default
@account.enable_service(:avatars)
@account.save!
@account.service_enabled?(:avatars).should be_true
get "/courses/#{@course.id}/gradebook2"
wait_for_ajaximations
driver.find_elements(:css, '.student-name').length.should == 2
driver.find_elements(:css, '.avatar img').length.should == 2
end
it "should link to a student's grades page" do
get "/courses/#{@course.id}/gradebook2"