Updated underscore (using _.invert())

The scss junk comes from trying to sync w/ several branches. I believe
it's right but mostly unnecessary (surprised it showed up).
Debugged the merge w/ cms-master
Fixed grace period to be absolute time difference not a date on the
client side.
This commit is contained in:
Don Mitchell
2012-12-11 14:18:13 -05:00
parent 0a91a98dd0
commit a46c1f4883
17 changed files with 167 additions and 398 deletions

View File

@@ -144,25 +144,21 @@ class CourseGradingModel:
@staticmethod
def update_grace_period_from_json(course_location, graceperiodjson):
"""
Update the course's default grace period.
Update the course's default grace period. Incoming dict is {hours: h, minutes: m} possibly as a
grace_period entry in an enclosing dict.
"""
if not isinstance(course_location, Location):
course_location = Location(course_location)
if not isinstance(graceperiodjson, dict):
graceperiodjson = {'grace_period' : graceperiodjson}
if 'grace_period' in graceperiodjson:
graceperiodjson = graceperiodjson['grace_period']
grace_time = converters.jsdate_to_time(graceperiodjson['grace_period'])
# NOTE: this does not handle > 24 hours
grace_rep = time.strftime("%H hours %M minutes %S seconds", grace_time)
grace_rep = " ".join(["%s %s" % (value, key) for (key, value) in graceperiodjson.iteritems()])
descriptor = get_modulestore(course_location).get_item(course_location)
descriptor.metadata['graceperiod'] = grace_rep
get_modulestore(course_location).update_metadata(course_location, descriptor.metadata)
return graceperiodjson
@staticmethod
def delete_grader(course_location, index):
"""
@@ -212,9 +208,7 @@ class CourseGradingModel:
rawgrace = descriptor.metadata.get('graceperiod', None)
if rawgrace:
parsedgrace = {str(key): val for (val, key) in re.findall('\s*(\d*)\s*(\w*)', rawgrace)}
gracedate = datetime.datetime.today()
gracedate = gracedate.replace(minute = int(parsedgrace.get('minutes',0)), hour = int(parsedgrace.get('hours',0)))
return gracedate.isoformat() + 'Z'
return parsedgrace
else: return None
@staticmethod
@@ -238,4 +232,4 @@ class CourseGradingModel:
if not 'short_label' in grader:
grader['short_label'] = ""
return grader
return grader

View File

@@ -1,28 +0,0 @@
<li>
<!-- FIXME what style should we use for initially hidden? --> <!-- TODO decide whether this should use codemirror -->
<form class="new-update-form">
<div class="row">
<label class="inline-label">Date:</label>
<!-- TODO replace w/ date widget and actual date (problem is that persisted version is "Month day" not an actual date obj -->
<input type="text" id="date-entry"
value="<%= updateModel.get('date') %>"></input>
</div>
<div class="row">
<textarea class="new-update-content text-editor"><%= updateModel.get('content') %></textarea>
</div>
<div class="row">
<!-- cid rather than id b/c new ones have cid's not id's -->
<a href="#" class="save-button" name="<%= updateModel.cid %>">Save</a>
<a href="#" class="cancel-button" name="<%= updateModel.cid %>">Cancel</a>
</div>
</form>
<h2>
<span class="calendar-icon"></span><span id="date-display"><%=
updateModel.get('date') %></span>
</h2>
<div class="update-contents"><%= updateModel.get('content') %></div>
<div class="row">
<a href="#" class="edit-button" name="<%- updateModel.cid %>">Edit</a>
<a href="#" class="delete-button" name="<%- updateModel.cid %>"">Delete</a>
</div>
</li>

View File

@@ -1,14 +0,0 @@
<!-- In order to enable better debugging of templates, put them in
the script tag section.
TODO add lazy load fn to load templates as needed (called
from backbone view initialize to set this.template of the view)
-->
<%block name="jsextra">
<script type="text/javascript" charset="utf-8">
// How do I load an html file server side so I can
// Precompiling your templates can be a big help when debugging errors you can't reproduce. This is because precompiled templates can provide line numbers and a stack trace, something that is not possible when compiling templates on the client. The source property is available on the compiled template function for easy precompilation.
// <script>CMS.course_info_update = <%= _.template(jstText).source %>;</script>
</script>
</%block>

View File

@@ -5,15 +5,12 @@ CMS.Models.Settings.CourseGradingPolicy = Backbone.Model.extend({
course_location : null,
graders : null, // CourseGraderCollection
grade_cutoffs : null, // CourseGradeCutoff model
grace_period : null // either null or seconds of grace period
grace_period : null // either null or { hours: n, minutes: m, ...}
},
parse: function(attributes) {
if (attributes['course_location']) {
attributes.course_location = new CMS.Models.Location(attributes.course_location, {parse:true});
}
if (attributes['grace_period']) {
attributes.grace_period = new Date(attributes.grace_period);
}
if (attributes['graders']) {
var graderCollection;
if (this.has('graders')) {
@@ -31,6 +28,23 @@ CMS.Models.Settings.CourseGradingPolicy = Backbone.Model.extend({
url : function() {
var location = this.get('course_location');
return '/' + location.get('org') + "/" + location.get('course') + '/settings/' + location.get('name') + '/section/grading';
},
gracePeriodToDate : function() {
var newDate = new Date();
if (this.has('grace_period') && this.get('grace_period')['hours'])
newDate.setHours(this.get('grace_period')['hours']);
else newDate.setHours(0);
if (this.has('grace_period') && this.get('grace_period')['minutes'])
newDate.setMinutes(this.get('grace_period')['minutes']);
else newDate.setMinutes(0);
if (this.has('grace_period') && this.get('grace_period')['seconds'])
newDate.setSeconds(this.get('grace_period')['seconds']);
else newDate.setSeconds(0);
return newDate;
},
dateToGracePeriod : function(date) {
return {hours : date.getHours(), minutes : date.getMinutes(), seconds : date.getSeconds() };
}
});

View File

@@ -292,8 +292,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
// instantiates an editor template for each update in the collection
// Because this calls render, put it after everything which render may depend upon to prevent race condition.
window.templateLoader.loadRemoteTemplate("course_info_update",
// TODO Where should the template reside? how to use the static.url to create the path?
"/static/coffee/src/client_templates/course_grade_policy.html",
"/static/client_templates/course_grade_policy.html",
function (raw_template) {
self.template = _.template(raw_template);
self.render();
@@ -306,6 +305,9 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
},
render: function() {
// prevent bootstrap race condition by event dispatch
if (!this.template) return;
// Create and render the grading type subs
var self = this;
var gradelist = this.$el.find('.course-grading-assignment-list');
@@ -322,7 +324,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
var graceEle = this.$el.find('#course-grading-graceperiod');
graceEle.timepicker({'timeFormat' : 'H:i'}); // init doesn't take setTime
graceEle.timepicker('setTime', (this.model.has('grace_period') ? this.model.get('grace_period') : new Date(0)));
graceEle.timepicker('setTime', this.model.gracePeriodToDate());
return this;
},
@@ -338,7 +340,7 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
switch (this.selectorToField[event.currentTarget.id]) {
case 'grace_period':
this.clearValidationErrors();
this.model.save('grace_period', $(event.currentTarget).timepicker('getTime'));
this.model.save('grace_period', this.model.dateToGracePeriod($(event.currentTarget).timepicker('getTime')));
break;
default:
@@ -379,7 +381,6 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
newBar = gradelist.children().last(); // get the dom object not the unparsed string
newBar.resizable({
handles: "e",
// TODO perhaps add a start which sets minWidth to next element's edge
containment : "parent",
start : this.startMoveClosure(),
resize : this.moveBarClosure(),

View File

@@ -181,11 +181,6 @@ code {
padding: 20px;
}
.details {
margin-bottom: 30px;
font-size: 14px;
}
h4 {
padding: 6px 14px;
border-bottom: 1px solid #cbd1db;
@@ -343,29 +338,4 @@ body.show-wip {
content: '';
@extend .spinner-icon;
}
}
.new-button {
@include grey-button;
padding: 20px 0;
text-align: center;
&.big {
display: block;
}
}
.edit-button.standard,
.delete-button.standard {
float: left;
@include white-button;
padding: 3px 10px 4px;
margin-left: 7px;
font-size: 12px;
font-weight: 400;
.edit-icon,
.delete-icon {
margin-right: 4px;
}
}

View File

@@ -51,14 +51,14 @@
@include button;
border: 1px solid $darkGrey;
border-radius: 3px;
@include linear-gradient(top, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0));
@include linear-gradient(top, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0) 60%);
background-color: #dfe5eb;
@include box-shadow(0 1px 0 rgba(255, 255, 255, .3) inset);
color: #778192;
color: #5d6779;
&:hover {
background-color: #f2f6f9;
color: #778192;
color: #5d6779;
}
}

View File

@@ -1,179 +1,77 @@
.course-info {
body.updates {
h2 {
margin-bottom: 24px;
font-size: 22px;
font-weight: 300;
}
.course-info-wrapper {
display: table;
width: 100%;
clear: both;
}
.main-column,
.course-handouts {
float: none;
display: table-cell;
}
.main-column {
border-radius: 3px 0 0 3px;
border-right-color: $mediumGrey;
}
.CodeMirror {
border: 1px solid #3c3c3c;
background: #fff;
color: #3c3c3c;
}
}
.course-updates {
padding: 30px 40px;
margin: 0;
.update-list > li {
padding: 34px 0 42px;
li {
padding: 24px 0 32px;
border-top: 1px solid #cbd1db;
}
&.editing {
position: relative;
z-index: 1001;
padding: 0;
border-top: none;
border-radius: 3px;
background: #fff;
.post-preview {
display: none;
}
}
h1 {
float: none;
font-size: 24px;
font-weight: 300;
}
h2 {
margin-bottom: 18px;
font-size: 14px;
font-weight: 700;
line-height: 30px;
color: #646464;
letter-spacing: 1px;
text-transform: uppercase;
}
h3 {
margin: 34px 0 11px;
font-size: 16px;
font-weight: 700;
}
h3 {
margin-bottom: 18px;
font-size: 14px;
font-weight: 700;
color: #646464;
letter-spacing: 1px;
text-transform: uppercase;
}
.update-contents {
padding-left: 30px;
p {
font-size: 16px;
line-height: 25px;
font-size: 14px;
line-height: 18px;
}
p + p {
margin-top: 25px;
}
.primary {
border: 1px solid #ddd;
background: #f6f6f6;
padding: 20px;
margin-top: 18px;
}
}
.new-update-button {
@include blue-button;
@include grey-button;
display: block;
text-align: center;
padding: 18px 0;
padding: 12px 0;
margin-bottom: 28px;
}
.new-update-form {
@include edit-box;
margin-bottom: 24px;
padding: 30px;
border: none;
textarea {
height: 180px;
}
}
.post-actions {
float: right;
.edit-button,
.delete-button{
float: left;
@include white-button;
padding: 3px 10px 4px;
margin-left: 7px;
font-size: 12px;
font-weight: 400;
.edit-icon,
.delete-icon {
margin-right: 4px;
}
}
}
}
.course-handouts {
width: 30%;
padding: 20px 30px;
margin: 0;
border-radius: 0 3px 3px 0;
border-left: none;
background: $lightGrey;
padding: 15px 20px;
h2 {
font-size: 18px;
font-weight: 700;
.new-handout-button {
@include grey-button;
display: block;
text-align: center;
padding: 12px 0;
margin-bottom: 28px;
}
.edit-button {
float: right;
@include white-button;
padding: 3px 10px 4px;
margin-left: 7px;
font-size: 12px;
font-weight: 400;
.edit-icon,
.delete-icon {
margin-right: 4px;
}
}
.handouts-content {
li {
margin-bottom: 10px;
font-size: 14px;
}
.treeview-handoutsnav li {
margin-bottom: 12px;
}
}
.edit-handouts-form {
@include edit-box;
position: absolute;
right: 0;
z-index: 10001;
width: 800px;
padding: 30px;
textarea {
height: 300px;
.new-handout-form {
@include edit-box;
margin-bottom: 24px;
}
}

View File

@@ -5,7 +5,12 @@ input.courseware-unit-search-input {
}
.courseware-overview {
.new-courseware-section-button {
@include grey-button;
display: block;
text-align: center;
padding: 12px 0;
}
}
.courseware-section {
@@ -141,18 +146,18 @@ input.courseware-unit-search-input {
.section-name-edit {
input {
font-size: 16px;
font-size: 16px;
}
.save-button {
@include blue-button;
padding: 10px 20px;
padding: 7px 20px 7px;
margin-right: 5px;
}
.cancel-button {
@include white-button;
padding: 10px 20px;
padding: 7px 20px 7px;
}
}
@@ -200,7 +205,7 @@ input.courseware-unit-search-input {
.new-section-name-save,
.new-subsection-name-save {
@include blue-button;
padding: 6px 20px 8px;
padding: 2px 20px 5px;
margin: 0 5px;
color: #fff !important;
}
@@ -208,7 +213,7 @@ input.courseware-unit-search-input {
.new-section-name-cancel,
.new-subsection-name-cancel {
@include white-button;
padding: 6px 20px 8px;
padding: 2px 20px 5px;
color: #8891a1 !important;
}

View File

@@ -89,7 +89,6 @@
.new-course-save {
@include blue-button;
// padding: ;
}
.new-course-cancel {

View File

@@ -137,10 +137,6 @@
height: 11px;
margin-right: 8px;
background: url(../img/plus-icon.png) no-repeat;
&.white {
background: url(../img/plus-icon-white.png) no-repeat;
}
}
.plus-icon-small {

View File

@@ -6,72 +6,6 @@
padding: 12px 0;
}
.unit-body {
padding: 30px 40px;
}
.components > li {
margin: 0;
border-radius: 0;
&.new-component-item {
margin-top: 20px;
}
}
.component {
border: 1px solid $mediumGrey;
border-top: none;
&:first-child {
border-top: 1px solid $mediumGrey;
}
&:hover {
border: 1px solid $mediumGrey;
border-top: none;
&:first-child {
border-top: 1px solid $mediumGrey;
}
.drag-handle {
background: url(../img/drag-handles.png) center no-repeat $lightGrey;
}
}
.drag-handle {
top: 0;
right: 0;
z-index: 11;
width: 35px;
border: none;
background: url(../img/drag-handles.png) center no-repeat $lightGrey;
&:hover {
background: url(../img/drag-handles.png) center no-repeat $lightGrey;
}
}
.component-actions {
top: 26px;
right: 44px;
}
}
.component.editing {
.xmodule_display {
display: none;
}
}
.xmodule_display {
padding: 20px 20px 22px;
font-size: 24px;
font-weight: 300;
background: $lightGrey;
}
.static-page-item {
position: relative;
margin: 10px 0;

View File

@@ -4,7 +4,6 @@
}
.main-column {
clear: both;
float: left;
width: 70%;
}
@@ -55,11 +54,94 @@
position: relative;
z-index: 10;
margin: 20px 40px;
border: 1px solid #d1ddec;
border-radius: 3px;
background: #fff;
@include transition(none);
&:hover {
border-color: #6696d7;
.drag-handle,
.component-actions a {
background-color: $blue;
}
.drag-handle {
border-color: $blue;
}
}
&.editing {
border-color: #6696d7;
.drag-handle,
.component-actions {
display: none;
}
}
&.component-placeholder {
border-color: #6696d7;
}
.xmodule_display {
padding: 40px 20px 20px;
}
.component-actions {
position: absolute;
top: 4px;
right: 4px;
@include transition(opacity .15s);
}
.edit-button,
.delete-button {
float: left;
padding: 3px 10px 4px;
margin-left: 3px;
border: 1px solid #fff;
border-radius: 3px;
background: #d1ddec;
font-size: 12px;
color: #fff;
@include transition(all .15s);
&:hover {
background-color: $blue;
color: #fff;
}
.edit-icon,
.delete-icon {
margin-right: 4px;
}
}
.drag-handle {
position: absolute;
display: block;
top: -1px;
right: -16px;
z-index: -1;
width: 15px;
height: 100%;
border-radius: 0 3px 3px 0;
border: 1px solid #d1ddec;
background: url(../img/white-drag-handles.png) center no-repeat #d1ddec;
cursor: move;
@include transition(all .15s);
}
&.new-component-item {
padding: 0;
border: none;
border-radius: 0;
border: 1px solid #8891a1;
border-radius: 3px;
@include linear-gradient(top, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0));
background-color: #d1dae3;
@include box-shadow(0 1px 0 rgba(255, 255, 255, .2) inset);
@include transition(background-color .15s, border-color .15s);
&.adding {
background-color: $blue;
@@ -141,63 +223,8 @@
}
}
.component {
border: 1px solid #d1ddec;
border-radius: 3px;
background: #fff;
@include transition(none);
&:hover {
border-color: #6696d7;
.drag-handle {
background-color: $blue;
border-color: $blue;
}
}
&.editing {
border-color: #6696d7;
.drag-handle,
.component-actions {
display: none;
}
}
&.component-placeholder {
border-color: #6696d7;
}
.component-actions {
position: absolute;
top: 7px;
right: 9px;
@include transition(opacity .15s);
a {
color: $darkGrey;
}
}
.drag-handle {
position: absolute;
display: block;
top: -1px;
right: -16px;
z-index: -1;
width: 15px;
height: 100%;
border-radius: 0 3px 3px 0;
border: 1px solid #d1ddec;
background: url(../img/white-drag-handles.png) center no-repeat #d1ddec;
cursor: move;
@include transition(all .15s);
}
}
.xmodule_display {
padding: 40px 20px 20px;
padding: 10px 20px;
}
.component-editor {

View File

@@ -2,6 +2,11 @@
.user-overview {
@extend .window;
padding: 30px 40px;
.details {
margin-bottom: 20px;
font-size: 14px;
}
}
.new-user-button {

View File

@@ -25,7 +25,6 @@
@import "modal";
@import "alerts";
@import "login";
@import "lms";
@import 'jquery-ui-calendar';
@import 'content-types';

File diff suppressed because one or more lines are too long