Commit c15cf074 by Mark L. Chang

Merge branch 'master' of github.com:MITx/mitx into mchang/acceptance-testing

parents e776a0dc 1159b14b
h2 { h2 {
margin-top: 0; margin-top: 0;
margin-bottom: 15px; margin-bottom: 15px;
width: flex-grid(2, 9);
padding-right: flex-gutter(9);
border-right: 1px dashed #ddd;
@include box-sizing(border-box);
display: table-cell;
vertical-align: top;
&.problem-header { &.problem-header {
section.staff { section.staff {
...@@ -15,12 +9,6 @@ h2 { ...@@ -15,12 +9,6 @@ h2 {
} }
} }
@media screen and (max-width:1120px) {
display: block;
width: auto;
border-right: 0;
}
@media print { @media print {
display: block; display: block;
width: auto; width: auto;
...@@ -29,16 +17,6 @@ h2 { ...@@ -29,16 +17,6 @@ h2 {
} }
section.problem { section.problem {
display: table-cell;
width: flex-grid(7, 9);
padding-left: flex-gutter(9);
@media screen and (max-width:1120px) {
display: block;
width: auto;
padding: 0;
}
@media print { @media print {
display: block; display: block;
width: auto; width: auto;
......
...@@ -36,7 +36,7 @@ class WikiRedirectTestCase(PageLoader): ...@@ -36,7 +36,7 @@ class WikiRedirectTestCase(PageLoader):
""" """
Test that requesting wiki URLs redirect properly to or out of classes. Test that requesting wiki URLs redirect properly to or out of classes.
An enrolled in student going from /courses/edX/toy/2012_Fall/profile An enrolled in student going from /courses/edX/toy/2012_Fall/progress
to /wiki/some/fake/wiki/page/ will redirect to to /wiki/some/fake/wiki/page/ will redirect to
/courses/edX/toy/2012_Fall/wiki/some/fake/wiki/page/ /courses/edX/toy/2012_Fall/wiki/some/fake/wiki/page/
...@@ -48,10 +48,10 @@ class WikiRedirectTestCase(PageLoader): ...@@ -48,10 +48,10 @@ class WikiRedirectTestCase(PageLoader):
self.enroll(self.toy) self.enroll(self.toy)
referer = reverse("profile", kwargs={ 'course_id' : self.toy.id }) referer = reverse("progress", kwargs={ 'course_id' : self.toy.id })
destination = reverse("wiki:get", kwargs={'path': 'some/fake/wiki/page/'}) destination = reverse("wiki:get", kwargs={'path': 'some/fake/wiki/page/'})
redirected_to = referer.replace("profile", "wiki/some/fake/wiki/page/") redirected_to = referer.replace("progress", "wiki/some/fake/wiki/page/")
resp = self.client.get( destination, HTTP_REFERER=referer) resp = self.client.get( destination, HTTP_REFERER=referer)
self.assertEqual(resp.status_code, 302 ) self.assertEqual(resp.status_code, 302 )
...@@ -77,11 +77,11 @@ class WikiRedirectTestCase(PageLoader): ...@@ -77,11 +77,11 @@ class WikiRedirectTestCase(PageLoader):
""" """
course_wiki_home = reverse('course_wiki', kwargs={'course_id' : course.id}) course_wiki_home = reverse('course_wiki', kwargs={'course_id' : course.id})
referer = reverse("profile", kwargs={ 'course_id' : self.toy.id }) referer = reverse("progress", kwargs={ 'course_id' : self.toy.id })
resp = self.client.get(course_wiki_home, follow=True, HTTP_REFERER=referer) resp = self.client.get(course_wiki_home, follow=True, HTTP_REFERER=referer)
course_wiki_page = referer.replace('profile', 'wiki/' + self.toy.wiki_slug + "/") course_wiki_page = referer.replace('progress', 'wiki/' + self.toy.wiki_slug + "/")
ending_location = resp.redirect_chain[-1][0] ending_location = resp.redirect_chain[-1][0]
ending_status = resp.redirect_chain[-1][1] ending_status = resp.redirect_chain[-1][1]
......
...@@ -303,7 +303,7 @@ class TestViewAuth(PageLoader): ...@@ -303,7 +303,7 @@ class TestViewAuth(PageLoader):
'instructor_dashboard', 'instructor_dashboard',
'gradebook', 'gradebook',
'grade_summary',)] 'grade_summary',)]
urls.append(reverse('student_profile', kwargs={'course_id': course.id, urls.append(reverse('student_progress', kwargs={'course_id': course.id,
'student_id': user(self.student).id})) 'student_id': user(self.student).id}))
return urls return urls
...@@ -388,7 +388,7 @@ class TestViewAuth(PageLoader): ...@@ -388,7 +388,7 @@ class TestViewAuth(PageLoader):
list of urls that students should be able to see only list of urls that students should be able to see only
after launch, but staff should see before after launch, but staff should see before
""" """
urls = reverse_urls(['info', 'courseware', 'profile'], course) urls = reverse_urls(['info', 'courseware', 'progress'], course)
urls.extend([ urls.extend([
reverse('book', kwargs={'course_id': course.id, 'book_index': book.title}) reverse('book', kwargs={'course_id': course.id, 'book_index': book.title})
for book in course.textbooks for book in course.textbooks
...@@ -411,7 +411,7 @@ class TestViewAuth(PageLoader): ...@@ -411,7 +411,7 @@ class TestViewAuth(PageLoader):
"""list of urls that only instructors/staff should be able to see""" """list of urls that only instructors/staff should be able to see"""
urls = reverse_urls(['instructor_dashboard','gradebook','grade_summary'], urls = reverse_urls(['instructor_dashboard','gradebook','grade_summary'],
course) course)
urls.append(reverse('student_profile', kwargs={'course_id': course.id, urls.append(reverse('student_progress', kwargs={'course_id': course.id,
'student_id': user(self.student).id})) 'student_id': user(self.student).id}))
return urls return urls
......
...@@ -258,11 +258,10 @@ def university_profile(request, org_id): ...@@ -258,11 +258,10 @@ def university_profile(request, org_id):
@login_required @login_required
@cache_control(no_cache=True, no_store=True, must_revalidate=True) @cache_control(no_cache=True, no_store=True, must_revalidate=True)
def profile(request, course_id, student_id=None): def progress(request, course_id, student_id=None):
""" User profile. Show username, location, etc, as well as grades . """ User progress. We show the grade bar and every problem score.
We need to allow the user to change some of these settings.
Course staff are allowed to see the profiles of students in their class. Course staff are allowed to see the progress of students in their class.
""" """
course = get_course_with_access(request.user, course_id, 'load') course = get_course_with_access(request.user, course_id, 'load')
staff_access = has_access(request.user, course, 'staff') staff_access = has_access(request.user, course, 'staff')
...@@ -276,28 +275,20 @@ def profile(request, course_id, student_id=None): ...@@ -276,28 +275,20 @@ def profile(request, course_id, student_id=None):
raise Http404 raise Http404
student = User.objects.get(id=int(student_id)) student = User.objects.get(id=int(student_id))
user_info = UserProfile.objects.get(user=student)
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(request.user, course) student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(request.user, course)
course_module = get_module(request.user, request, course.location, student_module_cache, course_id=course_id) course_module = get_module(request.user, request, course.location, student_module_cache, course_id=course_id)
courseware_summary = grades.progress_summary(student, course_module, course.grader, student_module_cache) courseware_summary = grades.progress_summary(student, course_module, course.grader, student_module_cache)
grade_summary = grades.grade(request.user, request, course, student_module_cache) grade_summary = grades.grade(request.user, request, course, student_module_cache)
context = {'name': user_info.name, context = {'course': course,
'username': student.username,
'location': user_info.location,
'language': user_info.language,
'email': student.email,
'course': course,
'csrf': csrf(request)['csrf_token'],
'courseware_summary': courseware_summary, 'courseware_summary': courseware_summary,
'grade_summary': grade_summary, 'grade_summary': grade_summary,
'staff_access': staff_access, 'staff_access': staff_access,
} }
context.update() context.update()
return render_to_response('profile.html', context) return render_to_response('progress.html', context)
......
...@@ -53,6 +53,18 @@ input[type="password"] { ...@@ -53,6 +53,18 @@ input[type="password"] {
} }
} }
input[type="reset"],
input[type="submit"],
input[type="button"],
button,
.button {
@extend .gray-button;
form & {
@extend .gray-button;
}
}
img { img {
max-width: 100%; max-width: 100%;
......
...@@ -6,28 +6,34 @@ h1.top-header { ...@@ -6,28 +6,34 @@ h1.top-header {
padding-bottom: lh(); padding-bottom: lh();
} }
.light-button, a.light-button { .button-reset {
border: 1px solid #ccc;
@include border-radius(3px);
@include box-shadow(inset 0 1px 0 #fff);
color: #666;
cursor: pointer;
font: 400 $body-font-size $body-font-family;
@include linear-gradient(#fff, lighten(#888, 40%));
padding: 4px 8px;
text-decoration: none;
text-shadow: none;
text-transform: none; text-transform: none;
letter-spacing: 0; letter-spacing: 0;
-webkit-font-smoothing: antialiased;
&:hover, &:focus { &:hover {
border: 1px solid #ccc;
@include linear-gradient(#fff, lighten(#888, 37%));
text-decoration: none; text-decoration: none;
} }
} }
.light-button, a.light-button, // only used in askbot as classes
.gray-button {
@include button(simple, #eee);
@extend .button-reset;
font-size: em(13);
}
.blue-button {
@include button(simple, $blue);
@extend .button-reset;
font-size: em(13);
}
.pink-button {
@include button(simple, $pink);
@extend .button-reset;
font-size: em(13);
}
.content { .content {
@include box-sizing(border-box); @include box-sizing(border-box);
display: table-cell; display: table-cell;
......
...@@ -43,8 +43,8 @@ div.discussion-wrapper aside { ...@@ -43,8 +43,8 @@ div.discussion-wrapper aside {
width: 27%; width: 27%;
float: right; float: right;
text-align: center; text-align: center;
padding-left: 0; padding: 4px 0;
padding-right: 0; text-transform: capitalize;
} }
input[type="text"] { input[type="text"] {
...@@ -300,7 +300,7 @@ div.discussion-wrapper aside { ...@@ -300,7 +300,7 @@ div.discussion-wrapper aside {
border-top: 0; border-top: 0;
a { a {
@extend .light-button; @extend .gray-button;
@include box-sizing(border-box); @include box-sizing(border-box);
display: block; display: block;
text-align: center; text-align: center;
......
...@@ -33,7 +33,7 @@ def url_class(url): ...@@ -33,7 +33,7 @@ def url_class(url):
<li class="wiki"><a href="${reverse('course_wiki', args=[course.id])}" class="${url_class('wiki')}">Wiki</a></li> <li class="wiki"><a href="${reverse('course_wiki', args=[course.id])}" class="${url_class('wiki')}">Wiki</a></li>
% endif % endif
% if user.is_authenticated(): % if user.is_authenticated():
<li class="profile"><a href="${reverse('profile', args=[course.id])}" class="${url_class('profile')}">Profile</a></li> <li class="profile"><a href="${reverse('progress', args=[course.id])}" class="${url_class('progress')}">Progress</a></li>
% endif % endif
% if staff_access: % if staff_access:
<li class="instructor"><a href="${reverse('instructor_dashboard', args=[course.id])}" class="${url_class('instructor')}">Instructor</a></li> <li class="instructor"><a href="${reverse('instructor_dashboard', args=[course.id])}" class="${url_class('instructor')}">Instructor</a></li>
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
%for student in students: %for student in students:
<tr> <tr>
<td> <td>
<a href="${reverse('student_profile', kwargs=dict(course_id=course_id, student_id=student['id']))}">${student['username']}</a> <a href="${reverse('student_progress', kwargs=dict(course_id=course_id, student_id=student['id']))}">${student['username']}</a>
</td> </td>
</tr> </tr>
%endfor %endfor
......
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
<%block name="headextra">
<%static:css group='course'/>
</%block>
<%namespace name="profile_graphs" file="profile_graphs.js"/>
<%block name="title"><title>Progress - edX 6.002x</title></%block>
<%!
from django.core.urlresolvers import reverse
%>
<%block name="js_extra">
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.stack.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.symbol.js')}"></script>
<script>
${profile_graphs.body(grade_summary, course.grade_cutoffs, "grade-detail-graph")}
</script>
</%block>
<%include file="course_navigation.html" args="active_page='progress'" />
<section class="container">
<div class="profile-wrapper">
<section class="course-info">
<header>
<h1>Course Progress</h1>
</header>
<div id="grade-detail-graph"></div>
<ol class="chapters">
%for chapter in courseware_summary:
%if not chapter['display_name'] == "hidden":
<li>
<h2>${ chapter['display_name'] }</h2>
<ol class="sections">
%for section in chapter['sections']:
<li>
<%
earned = section['section_total'].earned
total = section['section_total'].possible
percentageString = "{0:.0%}".format( float(earned)/total) if earned > 0 and total > 0 else ""
%>
<h3><a href="${reverse('courseware_section', kwargs=dict(course_id=course.id, chapter=chapter['url_name'], section=section['url_name']))}">
${ section['display_name'] }</a><span> ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )}</span></h3>
<p>
${section['format']}
%if 'due' in section and section['due']!="":
<em>
due ${section['due']}
</em>
%endif
</p>
%if len(section['scores']) > 0:
<section class="scores">
<h3> ${ "Problem Scores: " if section['graded'] else "Practice Scores: "} </h3>
<ol>
%for score in section['scores']:
<li>${"{0:.3n}/{1:.3n}".format(float(score.earned),float(score.possible))}</li>
%endfor
</ol>
</section>
%endif
</li> <!--End section-->
%endfor
</ol> <!--End sections-->
</li> <!--End chapter-->
%endif
%endfor
</ol> <!--End chapters-->
</section>
<section aria-label="Profile Navigation" class="user-info">
</section>
</div>
</section>
...@@ -138,11 +138,11 @@ if settings.COURSEWARE_ENABLED: ...@@ -138,11 +138,11 @@ if settings.COURSEWARE_ENABLED:
'courseware.views.index', name="courseware_chapter"), 'courseware.views.index', name="courseware_chapter"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$',
'courseware.views.index', name="courseware_section"), 'courseware.views.index', name="courseware_section"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/profile$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/progress$',
'courseware.views.profile', name="profile"), 'courseware.views.progress', name="progress"),
# Takes optional student_id for instructor use--shows profile as that student sees it. # Takes optional student_id for instructor use--shows profile as that student sees it.
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/profile/(?P<student_id>[^/]*)/$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/progress/(?P<student_id>[^/]*)/$',
'courseware.views.profile', name="student_profile"), 'courseware.views.progress', name="student_progress"),
# For the instructor # For the instructor
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/instructor$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/instructor$',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment