diff --git a/lms/static/images/search-icon.png b/lms/static/images/search-icon.png
new file mode 100644
index 0000000000..22b0d2d3c2
Binary files /dev/null and b/lms/static/images/search-icon.png differ
diff --git a/lms/static/js/jquery.gradebook.js b/lms/static/js/jquery.gradebook.js
new file mode 100644
index 0000000000..187e58189f
--- /dev/null
+++ b/lms/static/js/jquery.gradebook.js
@@ -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 = $('
');
+ var $rightShadow = $('');
+ 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);
+}
\ No newline at end of file
diff --git a/lms/static/sass/course.scss b/lms/static/sass/course.scss
index c874076a31..d3a74cb91b 100644
--- a/lms/static/sass/course.scss
+++ b/lms/static/sass/course.scss
@@ -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';
diff --git a/lms/static/sass/course/_gradebook.scss b/lms/static/sass/course/_gradebook.scss
index b94f5de178..cd3205149c 100644
--- a/lms/static/sass/course/_gradebook.scss
+++ b/lms/static/sass/course/_gradebook.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;
}
}
-}
\ No newline at end of file
+}
+
+
diff --git a/lms/static/sass/course/base/_extends.scss b/lms/static/sass/course/base/_extends.scss
index c5e61f593e..04eaf73094 100644
--- a/lms/static/sass/course/base/_extends.scss
+++ b/lms/static/sass/course/base/_extends.scss
@@ -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;
- }
- }
-}
diff --git a/lms/static/sass/course/layout/_courseware_header.scss b/lms/static/sass/course/layout/_courseware_header.scss
new file mode 100644
index 0000000000..dfa30b43a0
--- /dev/null
+++ b/lms/static/sass/course/layout/_courseware_header.scss
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lms/templates/gradebook.html b/lms/templates/gradebook.html
index a4a81a6868..787fc23c9a 100644
--- a/lms/templates/gradebook.html
+++ b/lms/templates/gradebook.html
@@ -6,6 +6,7 @@
+
%block>
<%block name="headextra">
@@ -19,6 +20,12 @@
.grade_None {color:LightGray;}
+
+
%block>
<%include file="course_navigation.html" args="active_page=''" />
@@ -28,50 +35,75 @@
Gradebook
- %if len(students) > 0:
-
- <%
- templateSummary = students[0]['grade_summary']
- %>
-
-
-
- | Student |
- %for section in templateSummary['section_breakdown']:
- ${section['label']} |
+
+
+
+ |
+
+ |
+
+
+
+ %for student in students:
+
+ |
+ ${student['username']}
+ |
+
%endfor
- Total |
-
-
- <%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
- %>
- ${ "{0:.0f}".format( 100 * fraction ) } |
- %def>
-
- %for student in students:
-
- |
- ${student['username']} |
- %for section in student['grade_summary']['section_breakdown']:
- ${percent_data( section['percent'] )}
- %endfor
- ${percent_data( student['grade_summary']['percent'])} |
-
- %endfor
+
+
+
+
+ %if len(students) > 0:
+
+
+ <%
+ templateSummary = students[0]['grade_summary']
+ %>
+
+
+ %for section in templateSummary['section_breakdown']:
+ | ${section['label']} |
+ %endfor
+ Total |
+
+
+
+ <%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
+ %>
+ ${ "{0:.0f}".format( 100 * fraction ) } |
+ %def>
+
+
+ %for student in students:
+
+ %for section in student['grade_summary']['section_breakdown']:
+ ${percent_data( section['percent'] )}
+ %endfor
+ | ${percent_data( student['grade_summary']['percent'])} |
+
+ %endfor
+
+
+
+
%endif
+
+