Commit a46c1f48 by Don Mitchell

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.
parent 0a91a98d
......@@ -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
\ No newline at end of file
return grader
<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>
\ No newline at end of file
<!-- 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>
\ No newline at end of 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() };
}
});
......
......@@ -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(),
......
......@@ -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;
}
}
\ No newline at end of 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;
}
}
......
.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;
h2 {
font-size: 18px;
font-weight: 700;
}
padding: 15px 20px;
.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;
}
.new-handout-button {
@include grey-button;
display: block;
text-align: center;
padding: 12px 0;
margin-bottom: 28px;
}
.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;
}
}
\ No newline at end of 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;
}
......
......@@ -89,7 +89,6 @@
.new-course-save {
@include blue-button;
// padding: ;
}
.new-course-cancel {
......
......@@ -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 {
......
......@@ -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;
......
......@@ -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 {
......
......@@ -2,6 +2,11 @@
.user-overview {
@extend .window;
padding: 30px 40px;
.details {
margin-bottom: 20px;
font-size: 14px;
}
}
.new-user-button {
......
......@@ -25,7 +25,6 @@
@import "modal";
@import "alerts";
@import "login";
@import "lms";
@import 'jquery-ui-calendar';
@import 'content-types';
......
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