Merge pull request #409 from MITx/feature/tomg/fall-design
started gradebook design; moved a few nav classes
This commit is contained in:
BIN
lms/static/images/search-icon.png
Normal file
BIN
lms/static/images/search-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
76
lms/static/js/jquery.gradebook.js
Normal file
76
lms/static/js/jquery.gradebook.js
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
|
||||
|
||||
var Gradebook = function($element) {
|
||||
var _this = this;
|
||||
var $element = $element;
|
||||
var $grades = $element.find('.grades');
|
||||
var $gradeTable = $element.find('.grade-table');
|
||||
var $leftShadow = $('<div class="left-shadow"></div>');
|
||||
var $rightShadow = $('<div class="right-shadow"></div>');
|
||||
var tableHeight = $gradeTable.height();
|
||||
var maxScroll = $gradeTable.width() - $grades.width();
|
||||
var $body = $('body');
|
||||
var mouseOrigin;
|
||||
var tableOrigin;
|
||||
|
||||
var startDrag = function(e) {
|
||||
mouseOrigin = e.pageX;
|
||||
tableOrigin = $gradeTable.position().left;
|
||||
$body.css('-webkit-user-select', 'none');
|
||||
$body.bind('mousemove', moveDrag);
|
||||
$body.bind('mouseup', stopDrag);
|
||||
};
|
||||
|
||||
var moveDrag = function(e) {
|
||||
var offset = e.pageX - mouseOrigin;
|
||||
var targetLeft = clamp(tableOrigin + offset, -maxScroll, 0);
|
||||
|
||||
updateHorizontalPosition(targetLeft);
|
||||
|
||||
setShadows(targetLeft);
|
||||
};
|
||||
|
||||
var stopDrag = function(e) {
|
||||
$body.css('-webkit-user-select', 'auto');
|
||||
$body.unbind('mousemove', moveDrag);
|
||||
$body.unbind('mouseup', stopDrag);
|
||||
};
|
||||
|
||||
var setShadows = function(left) {
|
||||
var padding = 30;
|
||||
|
||||
var leftPercent = clamp(-left / padding, 0, 1);
|
||||
$leftShadow.css('opacity', leftPercent);
|
||||
|
||||
var rightPercent = clamp((maxScroll + left) / padding, 0, 1);
|
||||
$rightShadow.css('opacity', rightPercent);
|
||||
};
|
||||
|
||||
var clamp = function(val, min, max) {
|
||||
if(val > max) return max;
|
||||
if(val < min) return min;
|
||||
return val;
|
||||
};
|
||||
|
||||
var updateWidths = function(e) {
|
||||
maxScroll = $gradeTable.width() - $grades.width();
|
||||
var targetLeft = clamp($gradeTable.position().left, -maxScroll, 0);
|
||||
updateHorizontalPosition(targetLeft);
|
||||
setShadows(targetLeft);
|
||||
}
|
||||
|
||||
var updateHorizontalPosition = function(left) {
|
||||
$gradeTable.css({
|
||||
'left': left + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
$leftShadow.css('height', tableHeight + 'px');
|
||||
$rightShadow.css('height', tableHeight + 'px');
|
||||
$grades.append($leftShadow).append($rightShadow);
|
||||
setShadows(0);
|
||||
$grades.css('height', tableHeight);
|
||||
$gradeTable.bind('mousedown', startDrag);
|
||||
$(window).bind('resize', updateWidths);
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
@import 'shared/tooltips';
|
||||
|
||||
// Course base / layout styles
|
||||
@import 'course/layout/courseware_subnav';
|
||||
@import 'course/layout/courseware_header';
|
||||
@import 'course/base/base';
|
||||
@import 'course/base/extends';
|
||||
@import 'module/module-styles.scss';
|
||||
|
||||
@@ -1,11 +1,203 @@
|
||||
$cell-border-color: #e1e1e1;
|
||||
$table-border-color: #c8c8c8;
|
||||
|
||||
div.gradebook-wrapper {
|
||||
@extend .table-wrapper;
|
||||
|
||||
section.gradebook-content {
|
||||
@extend .content;
|
||||
|
||||
.student-search {
|
||||
padding: 0 20px 0 15px;
|
||||
}
|
||||
|
||||
.student-search-field {
|
||||
width: 100%;
|
||||
height: 27px;
|
||||
padding: 0 15px 0 35px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 13px;
|
||||
border: 1px solid $table-border-color;
|
||||
background: url(../images/search-icon.png) no-repeat 9px center #f6f6f6;
|
||||
font-family: $sans-serif;
|
||||
font-size: 11px;
|
||||
@include box-shadow(0 1px 4px rgba(0, 0, 0, .12) inset);
|
||||
outline: none;
|
||||
@include transition(border-color .15s);
|
||||
|
||||
&::-webkit-input-placeholder,
|
||||
&::-moz-input-placeholder {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: #1d9dd9;
|
||||
}
|
||||
}
|
||||
|
||||
.student-table {
|
||||
float: left;
|
||||
// width: 264px;
|
||||
width: 24%;
|
||||
border-radius: 3px 0 0 3px;
|
||||
color: #3c3c3c;
|
||||
|
||||
th {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
tr:first-child td {
|
||||
border-top: 1px solid $table-border-color;
|
||||
border-radius: 5px 0 0 0;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: 1px solid $table-border-color;
|
||||
border-radius: 0 0 0 5px;
|
||||
}
|
||||
|
||||
td {
|
||||
height: 50px;
|
||||
padding-left: 20px;
|
||||
border-bottom: 1px solid $cell-border-color;
|
||||
border-left: 1px solid $table-border-color;
|
||||
background: #f3f3f3;
|
||||
font-size: 13px;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
tr:nth-child(odd) td {
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
}
|
||||
|
||||
.grades {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 76%;
|
||||
overflow: hidden;
|
||||
|
||||
.left-shadow,
|
||||
.right-shadow {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 9999;
|
||||
width: 20px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.left-shadow {
|
||||
left: 0;
|
||||
background: -webkit-linear-gradient(left, rgba(0, 0, 0, .1), rgba(0, 0, 0, 0) 20%), -webkit-linear-gradient(left, rgba(0, 0, 0, .1), rgba(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
.right-shadow {
|
||||
right: 0;
|
||||
background: -webkit-linear-gradient(right, rgba(0, 0, 0, .1), rgba(0, 0, 0, 0) 20%), -webkit-linear-gradient(right, rgba(0, 0, 0, .1), rgba(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
.grade-table {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1000px;
|
||||
cursor: move;
|
||||
-webkit-transition: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
td,
|
||||
th {
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
thead th {
|
||||
position: relative;
|
||||
height: 50px;
|
||||
background: -webkit-linear-gradient(top, $cell-border-color, #ddd);
|
||||
font-size: 10px;
|
||||
line-height: 10px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
box-shadow: 0 1px 0 $table-border-color inset, 0 2px 0 rgba(255, 255, 255, .7) inset;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 9999;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, .15));
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-radius: 5px 0 0 0;
|
||||
box-shadow: 1px 1px 0 $table-border-color inset, 1px 2px 0 rgba(255, 255, 255, .7) inset;
|
||||
|
||||
&:before {
|
||||
display: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 3px 0 0;
|
||||
box-shadow: -1px 1px 0 $table-border-color inset, -1px 2px 0 rgba(255, 255, 255, .7) inset;
|
||||
}
|
||||
|
||||
.assignment {
|
||||
margin: 9px 0;
|
||||
}
|
||||
|
||||
.type,
|
||||
.number,
|
||||
.max {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.max {
|
||||
height: 12px;
|
||||
background: -webkit-linear-gradient(top, #c6c6c6, #bababa);
|
||||
font-size: 9px;
|
||||
line-height: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
border-right: 1px solid $table-border-color;
|
||||
}
|
||||
|
||||
tr:first-child td {
|
||||
border-top: 1px solid $table-border-color;
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: 1px solid $table-border-color;
|
||||
}
|
||||
|
||||
td {
|
||||
height: 50px;
|
||||
border-bottom: 1px solid $cell-border-color;
|
||||
background: #f3f3f3;
|
||||
font-size: 13px;
|
||||
line-height: 50px;
|
||||
border-left: 1px solid $cell-border-color;
|
||||
}
|
||||
|
||||
tr:nth-child(odd) td {
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
@extend .top-header;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -173,29 +173,3 @@ h1.top-header {
|
||||
@include transition( all, .2s, $ease-in-out-quad);
|
||||
}
|
||||
|
||||
.global {
|
||||
.find-courses-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
display: block;
|
||||
float: left;
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0;
|
||||
line-height: 40px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
text-transform: none;
|
||||
white-space: nowrap;
|
||||
width: 700px;
|
||||
|
||||
.provider {
|
||||
font: inherit;
|
||||
font-weight: bold;
|
||||
color: #6d6d6d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
85
lms/static/sass/course/layout/_courseware_header.scss
Normal file
85
lms/static/sass/course/layout/_courseware_header.scss
Normal file
@@ -0,0 +1,85 @@
|
||||
nav.course-material {
|
||||
@include clearfix;
|
||||
@include box-sizing(border-box);
|
||||
background: #f6f6f6;
|
||||
border-bottom: 1px solid rgb(200,200,200);
|
||||
margin: 0px auto 0px;
|
||||
padding: 0px;
|
||||
width: 100%;
|
||||
|
||||
.inner-wrapper {
|
||||
margin: 0 auto;
|
||||
max-width: 1200px;
|
||||
width: flex-grid(12);
|
||||
}
|
||||
|
||||
ol.course-tabs {
|
||||
@include border-top-radius(4px);
|
||||
@include clearfix;
|
||||
padding: 10px 0 0 0;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
list-style: none;
|
||||
|
||||
a {
|
||||
color: darken($lighter-base-font-color, 20%);
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 8px 13px 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px rgb(255,255,255);
|
||||
|
||||
&:hover {
|
||||
color: $base-font-color;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: rgb(255,255,255);
|
||||
border: 1px solid rgb(200,200,200);
|
||||
border-bottom: 0px;
|
||||
@include border-top-radius(4px);
|
||||
@include box-shadow(0 2px 0 0 rgba(255,255,255, 1));
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course-content {
|
||||
margin-top: 30px;
|
||||
|
||||
.courseware {
|
||||
min-height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.global {
|
||||
.find-courses-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
display: block;
|
||||
width: 700px;
|
||||
float: left;
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
line-height: 40px;
|
||||
letter-spacing: 0;
|
||||
text-transform: none;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
|
||||
.provider {
|
||||
font: inherit;
|
||||
font-weight: bold;
|
||||
color: #6d6d6d;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
<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 type="text/javascript" src="${static.url('js/jquery.gradebook.js')}"></script>
|
||||
</%block>
|
||||
|
||||
<%block name="headextra">
|
||||
@@ -19,6 +20,12 @@
|
||||
.grade_None {color:LightGray;}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
var gradebook = new Gradebook($('.gradebook-content'));
|
||||
});
|
||||
</script>
|
||||
|
||||
</%block>
|
||||
|
||||
<%include file="course_navigation.html" args="active_page=''" />
|
||||
@@ -28,50 +35,75 @@
|
||||
<section class="gradebook-content">
|
||||
<h1>Gradebook</h1>
|
||||
|
||||
%if len(students) > 0:
|
||||
<table>
|
||||
<%
|
||||
templateSummary = students[0]['grade_summary']
|
||||
%>
|
||||
|
||||
|
||||
<tr> <!-- Header Row -->
|
||||
<th>Student</th>
|
||||
%for section in templateSummary['section_breakdown']:
|
||||
<th>${section['label']}</th>
|
||||
<table class="student-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<form class="student-search">
|
||||
<input type="search" class="student-search-field" placeholder="Search students" />
|
||||
</form>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
%for student in students:
|
||||
<tr>
|
||||
<td>
|
||||
<a href="${reverse('student_profile', kwargs=dict(course_id=course_id, student_id=student['id']))}">${student['username']}</a>
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
|
||||
<%def name="percent_data(fraction)">
|
||||
<%
|
||||
letter_grade = 'None'
|
||||
if fraction > 0:
|
||||
letter_grade = 'F'
|
||||
for grade in ['A', 'B', 'C']:
|
||||
if fraction >= course.grade_cutoffs[grade]:
|
||||
letter_grade = grade
|
||||
break
|
||||
|
||||
data_class = "grade_" + letter_grade
|
||||
%>
|
||||
<td class="${data_class}" data-percent="${fraction}">${ "{0:.0f}".format( 100 * fraction ) }</td>
|
||||
</%def>
|
||||
|
||||
%for student in students:
|
||||
<tr>
|
||||
<td><a href="${reverse('student_profile',
|
||||
kwargs=dict(course_id=course_id,
|
||||
student_id=student['id']))}">
|
||||
${student['username']}</a></td>
|
||||
%for section in student['grade_summary']['section_breakdown']:
|
||||
${percent_data( section['percent'] )}
|
||||
%endfor
|
||||
<th>${percent_data( student['grade_summary']['percent'])}</th>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
%if len(students) > 0:
|
||||
<div class="grades">
|
||||
<table class="grade-table">
|
||||
<%
|
||||
templateSummary = students[0]['grade_summary']
|
||||
%>
|
||||
<thead>
|
||||
<tr> <!-- Header Row -->
|
||||
%for section in templateSummary['section_breakdown']:
|
||||
<th>${section['label']}</th>
|
||||
%endfor
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<%def name="percent_data(fraction)">
|
||||
<%
|
||||
letter_grade = 'None'
|
||||
if fraction > 0:
|
||||
letter_grade = 'F'
|
||||
for grade in ['A', 'B', 'C']:
|
||||
if fraction >= course.grade_cutoffs[grade]:
|
||||
letter_grade = grade
|
||||
break
|
||||
|
||||
data_class = "grade_" + letter_grade
|
||||
%>
|
||||
<td class="${data_class}" data-percent="${fraction}">${ "{0:.0f}".format( 100 * fraction ) }</td>
|
||||
</%def>
|
||||
|
||||
<tbody>
|
||||
%for student in students:
|
||||
<tr>
|
||||
%for section in student['grade_summary']['section_breakdown']:
|
||||
${percent_data( section['percent'] )}
|
||||
%endfor
|
||||
<td>${percent_data( student['grade_summary']['percent'])}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
%endif
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user