Merge branch 'feature/cas/speed-editor' of github.com:MITx/mitx into feature/cas/speed-editor
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
from cms.djangoapps.contentstore.tests.test_course_settings import CourseTestCase
|
||||
from django.core.urlresolvers import reverse
|
||||
import json
|
||||
from cms.djangoapps.contentstore.course_info_model import update_course_updates
|
||||
|
||||
|
||||
class CourseUpdateTest(CourseTestCase):
|
||||
def test_course_update(self):
|
||||
@@ -14,14 +12,17 @@ class CourseUpdateTest(CourseTestCase):
|
||||
content = '<iframe width="560" height="315" src="http://www.youtube.com/embed/RocY-Jd93XU" frameborder="0"></iframe>'
|
||||
payload = { 'content' : content,
|
||||
'date' : 'January 8, 2013'}
|
||||
# No means to post w/ provided_id missing. django doesn't handle. So, go direct for the create
|
||||
payload = update_course_updates(['i4x', self.course_location.org, self.course_location.course, 'course_info', "updates"] , payload)
|
||||
url = reverse('course_info', kwargs={'org' : self.course_location.org, 'course' : self.course_location.course,
|
||||
'provided_id' : ''})
|
||||
|
||||
resp = self.client.post(url, json.dumps(payload), "application/json")
|
||||
|
||||
payload= json.loads(resp.content)
|
||||
|
||||
self.assertHTMLEqual(content, payload['content'], "single iframe")
|
||||
|
||||
url = reverse('course_info', kwargs={'org' : self.course_location.org, 'course' : self.course_location.course,
|
||||
'provided_id' : payload['id']})
|
||||
|
||||
self.assertHTMLEqual(content, payload['content'], "single iframe")
|
||||
|
||||
content += '<div>div <p>p</p></div>'
|
||||
payload['content'] = content
|
||||
resp = self.client.post(url, json.dumps(payload), "application/json")
|
||||
|
||||
@@ -975,6 +975,11 @@ def course_info_updates(request, org, course, provided_id=None):
|
||||
# ??? No way to check for access permission afaik
|
||||
# get current updates
|
||||
location = ['i4x', org, course, 'course_info', "updates"]
|
||||
|
||||
# Hmmm, provided_id is coming as empty string on create whereas I believe it used to be None :-(
|
||||
# Possibly due to my removing the seemingly redundant pattern in urls.py
|
||||
if provided_id == '':
|
||||
provided_id = None
|
||||
|
||||
# check that logged in user has permissions to this item
|
||||
if not has_access(request.user, location):
|
||||
|
||||
@@ -56,7 +56,7 @@ class CMS.Views.ModuleEdit extends Backbone.View
|
||||
event.preventDefault()
|
||||
data = @module.save()
|
||||
data.metadata = _.extend(data.metadata, @metadata())
|
||||
$modalCover.hide()
|
||||
@hideModal()
|
||||
@model.save(data).done( =>
|
||||
# # showToastMessage("Your changes have been saved.", null, 3)
|
||||
@module = null
|
||||
@@ -70,11 +70,15 @@ class CMS.Views.ModuleEdit extends Backbone.View
|
||||
event.preventDefault()
|
||||
@$el.removeClass('editing')
|
||||
@$component_editor().slideUp(150)
|
||||
@hideModal()
|
||||
|
||||
hideModal: ->
|
||||
$modalCover.hide()
|
||||
$modalCover.removeClass('is-fixed')
|
||||
|
||||
clickEditButton: (event) ->
|
||||
event.preventDefault()
|
||||
@$el.addClass('editing')
|
||||
$modalCover.show()
|
||||
$modalCover.show().addClass('is-fixed')
|
||||
@$component_editor().slideDown(150)
|
||||
@loadEdit()
|
||||
|
||||
@@ -29,9 +29,7 @@ $(document).ready(function() {
|
||||
$('.expand-collapse-icon').bind('click', toggleSubmodules);
|
||||
$('.visibility-options').bind('change', setVisibility);
|
||||
|
||||
$('.unit-history ol a').bind('click', showHistoryModal);
|
||||
$modal.bind('click', hideModal);
|
||||
$modalCover.bind('click', hideHistoryModal);
|
||||
$modalCover.bind('click', hideModal);
|
||||
$('.assets .upload-button').bind('click', showUploadModal);
|
||||
$('.upload-modal .close-button').bind('click', hideModal);
|
||||
@@ -41,7 +39,13 @@ $(document).ready(function() {
|
||||
$('.unit .item-actions .delete-button').bind('click', deleteUnit);
|
||||
$('.new-unit-item').bind('click', createNewUnit);
|
||||
|
||||
$('.collapse-all-button').bind('click', collapseAll);
|
||||
// toggling overview section details
|
||||
$(function(){
|
||||
if($('.courseware-section').length > 0) {
|
||||
$('.toggle-button-sections').addClass('is-shown');
|
||||
}
|
||||
});
|
||||
$('.toggle-button-sections').bind('click', toggleSections);
|
||||
|
||||
// autosave when a field is updated on the subsection page
|
||||
$body.on('keyup', '.subsection-display-name-input, .unit-subtitle, .policy-list-value', checkForNewValue);
|
||||
@@ -125,9 +129,30 @@ $(document).ready(function() {
|
||||
});
|
||||
});
|
||||
|
||||
function collapseAll(e) {
|
||||
$('.branch').addClass('collapsed');
|
||||
$('.expand-collapse-icon').removeClass('collapse').addClass('expand');
|
||||
// function collapseAll(e) {
|
||||
// $('.branch').addClass('collapsed');
|
||||
// $('.expand-collapse-icon').removeClass('collapse').addClass('expand');
|
||||
// }
|
||||
|
||||
function toggleSections(e) {
|
||||
e.preventDefault();
|
||||
|
||||
$section = $('.courseware-section');
|
||||
sectionCount = $section.length;
|
||||
$button = $(this);
|
||||
$labelCollapsed = $('<i class="ss-icon ss-symbolicons-block">up</i> <span class="label">Collapse All Sections</span>');
|
||||
$labelExpanded = $('<i class="ss-icon ss-symbolicons-block">down</i> <span class="label">Expand All Sections</span>');
|
||||
|
||||
var buttonLabel = $button.hasClass('is-activated') ? $labelCollapsed : $labelExpanded;
|
||||
$button.toggleClass('is-activated').html(buttonLabel);
|
||||
|
||||
if($button.hasClass('is-activated')) {
|
||||
$section.addClass('collapsed');
|
||||
$section.find('.expand-collapse-icon').removeClass('collapsed').addClass('expand');
|
||||
} else {
|
||||
$section.removeClass('collapsed');
|
||||
$section.find('.expand-collapse-icon').removeClass('expand').addClass('collapse');
|
||||
}
|
||||
}
|
||||
|
||||
function editSectionPublishDate(e) {
|
||||
@@ -498,9 +523,14 @@ function hideModal(e) {
|
||||
if(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
$('.file-input').unbind('change', startUpload);
|
||||
$modal.hide();
|
||||
$modalCover.hide();
|
||||
// Unit editors do not want the modal cover to hide when users click outside
|
||||
// of the editor. Users must press Cancel or Save to exit the editor.
|
||||
// module_edit adds and removes the "is-fixed" class.
|
||||
if (!$modalCover.hasClass("is-fixed")) {
|
||||
$('.file-input').unbind('change', startUpload);
|
||||
$modal.hide();
|
||||
$modalCover.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function onKeyUp(e) {
|
||||
@@ -530,21 +560,6 @@ function closeComponentEditor(e) {
|
||||
$(this).closest('.xmodule_edit').removeClass('editing').find('.component-editor').slideUp(150);
|
||||
}
|
||||
|
||||
|
||||
function showHistoryModal(e) {
|
||||
e.preventDefault();
|
||||
|
||||
$modal.show();
|
||||
$modalCover.show();
|
||||
}
|
||||
|
||||
function hideHistoryModal(e) {
|
||||
e.preventDefault();
|
||||
|
||||
$modal.hide();
|
||||
$modalCover.hide();
|
||||
}
|
||||
|
||||
function showDateSetter(e) {
|
||||
e.preventDefault();
|
||||
var $block = $(this).closest('.due-date-input');
|
||||
|
||||
@@ -388,6 +388,9 @@ 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
|
||||
if (this.model.has('grace_period')) graceEle.timepicker('setTime', this.model.gracePeriodToDate());
|
||||
// remove any existing listeners to keep them from piling on b/c render gets called frequently
|
||||
graceEle.off('change', this.setGracePeriod);
|
||||
graceEle.on('change', this, this.setGracePeriod);
|
||||
|
||||
return this;
|
||||
},
|
||||
@@ -398,14 +401,16 @@ CMS.Views.Settings.Grading = CMS.Views.ValidatingView.extend({
|
||||
fieldToSelectorMap : {
|
||||
'grace_period' : 'course-grading-graceperiod'
|
||||
},
|
||||
setGracePeriod : function(event) {
|
||||
event.data.clearValidationErrors();
|
||||
var newVal = event.data.model.dateToGracePeriod($(event.currentTarget).timepicker('getTime'));
|
||||
if (event.data.model.get('grace_period') != newVal) event.data.model.save('grace_period', newVal);
|
||||
},
|
||||
updateModel : function(event) {
|
||||
if (!this.selectorToField[event.currentTarget.id]) return;
|
||||
|
||||
switch (this.selectorToField[event.currentTarget.id]) {
|
||||
case 'grace_period':
|
||||
this.clearValidationErrors();
|
||||
var newVal = this.model.dateToGracePeriod($(event.currentTarget).timepicker('getTime'));
|
||||
if (this.model.get('grace_period') != newVal) this.model.save('grace_period', newVal);
|
||||
case 'grace_period': // handled above
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -422,6 +422,14 @@ input.courseware-unit-search-input {
|
||||
float: left;
|
||||
margin: 29px 6px 16px 16px;
|
||||
@include transition(none);
|
||||
|
||||
&.expand {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.drag-handle {
|
||||
@@ -501,14 +509,31 @@ input.courseware-unit-search-input {
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-all-button {
|
||||
.toggle-button-sections {
|
||||
display: none;
|
||||
position: relative;
|
||||
float: right;
|
||||
margin-top: 10px;
|
||||
|
||||
font-size: 13px;
|
||||
color: $darkGrey;
|
||||
|
||||
.collapse-all-icon {
|
||||
margin-right: 6px;
|
||||
&.is-shown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ss-icon {
|
||||
@include border-radius(20px);
|
||||
position: relative;
|
||||
top: -1px;
|
||||
display: inline-block;
|
||||
margin-right: 2px;
|
||||
line-height: 5px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -245,8 +245,8 @@
|
||||
|
||||
&.editing {
|
||||
border: 1px solid $lightBluishGrey2;
|
||||
z-index: 9999;
|
||||
|
||||
z-index: auto;
|
||||
|
||||
.drag-handle,
|
||||
.component-actions {
|
||||
display: none;
|
||||
@@ -284,12 +284,17 @@
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.wrapper-component-editor {
|
||||
z-index: 9999;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.component-editor {
|
||||
@include edit-box;
|
||||
@include box-shadow(none);
|
||||
display: none;
|
||||
padding: 20px;
|
||||
border-radius: 2px 2px 0 0;
|
||||
@include box-shadow(none);
|
||||
|
||||
.metadata_edit {
|
||||
margin-bottom: 20px;
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<div class="component-editor">
|
||||
<div class="module-editor">
|
||||
${editor}
|
||||
</div>
|
||||
<a href="#" class="save-button">Save</a>
|
||||
<a href="#" class="cancel-button">Cancel</a>
|
||||
<div class="wrapper wrapper-component-editor">
|
||||
<div class="component-editor">
|
||||
<div class="module-editor">
|
||||
${editor}
|
||||
</div>
|
||||
<a href="#" class="save-button">Save</a>
|
||||
<a href="#" class="cancel-button">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="component-actions">
|
||||
<a href="#" class="edit-button standard"><span class="edit-icon"></span>Edit</a>
|
||||
<a href="#" class="delete-button standard"><span class="delete-icon"></span>Delete</a>
|
||||
</div>
|
||||
<a data-tooltip="Drag to reorder" href="#" class="drag-handle"></a>
|
||||
${preview}
|
||||
${preview}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
<div class="inner-wrapper">
|
||||
<div class="page-actions">
|
||||
<a href="#" class="new-button new-courseware-section-button"><span class="plus-icon white"></span> New Section</a>
|
||||
<a href="#" class="collapse-all-button"><span class="collapse-all-icon"></span>Collapse All</a>
|
||||
<a href="#" class="toggle-button toggle-button-sections"><i class="ss-icon ss-symbolicons-block">up</i> <span class="label">Collapse All Sections</span></a>
|
||||
</div>
|
||||
<article class="courseware-overview" data-course-id="${context_course.location.url()}">
|
||||
% for section in sections:
|
||||
|
||||
Reference in New Issue
Block a user