Merge branch 'feature/cale/cms-master' into fix/cale/edge-bugs
Conflicts: cms/static/js/base.js
This commit is contained in:
@@ -31,6 +31,7 @@ from django import forms
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.x_module import ModuleSystem
|
||||
from xmodule.error_module import ErrorDescriptor
|
||||
from xmodule.errortracker import exc_info_to_str
|
||||
@@ -41,6 +42,7 @@ from mitxmako.shortcuts import render_to_response, render_to_string
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule_modifiers import replace_static_urls, wrap_xmodule
|
||||
from xmodule.exceptions import NotFoundError
|
||||
from xmodule.timeparse import parse_time, stringify_time
|
||||
from functools import partial
|
||||
from itertools import groupby
|
||||
from operator import attrgetter
|
||||
@@ -107,9 +109,10 @@ def index(request):
|
||||
courses = modulestore().get_items(['i4x', None, None, 'course', None])
|
||||
|
||||
# filter out courses that we don't have access to
|
||||
courses = filter(lambda course: has_access(request.user, course.location), courses)
|
||||
courses = filter(lambda course: has_access(request.user, course.location) and course.location.course != 'templates', courses)
|
||||
|
||||
return render_to_response('index.html', {
|
||||
'new_course_template' : Location('i4x', 'edx', 'templates', 'course', 'Empty'),
|
||||
'courses': [(course.metadata.get('display_name'),
|
||||
reverse('course_index', args=[
|
||||
course.location.org,
|
||||
@@ -869,6 +872,46 @@ def asset_index(request, org, course, name):
|
||||
def edge(request):
|
||||
return render_to_response('university_profiles/edge.html', {})
|
||||
|
||||
@login_required
|
||||
@expect_json
|
||||
def create_new_course(request):
|
||||
template = Location(request.POST['template'])
|
||||
org = request.POST.get('org')
|
||||
number = request.POST.get('number')
|
||||
display_name = request.POST.get('display_name')
|
||||
|
||||
dest_location = Location('i4x', org, number, 'course', Location.clean(display_name))
|
||||
|
||||
# see if the course already exists
|
||||
existing_course = None
|
||||
try:
|
||||
existing_course = modulestore('direct').get_item(dest_location)
|
||||
except ItemNotFoundError:
|
||||
pass
|
||||
|
||||
if existing_course is not None:
|
||||
return HttpResponse(json.dumps({'ErrMsg': 'There is already a course defined with this name.'}))
|
||||
|
||||
logging.debug(dest_location)
|
||||
logging.debug(template)
|
||||
|
||||
new_course = modulestore('direct').clone_item(template, dest_location)
|
||||
|
||||
if display_name is not None:
|
||||
new_course.metadata['display_name'] = display_name
|
||||
|
||||
# we need a 'data_dir' for legacy reasons
|
||||
new_course.metadata['data_dir'] = uuid4().hex
|
||||
|
||||
# set a default start date to now
|
||||
new_course.metadata['start'] = stringify_time(time.gmtime())
|
||||
|
||||
modulestore('direct').update_metadata(new_course.location.url(), new_course.own_metadata)
|
||||
|
||||
create_all_course_groups(request.user, new_course.location)
|
||||
|
||||
return HttpResponse(json.dumps({'id': new_course.location.url()}))
|
||||
|
||||
@ensure_csrf_cookie
|
||||
@login_required
|
||||
def import_course(request, org, course, name):
|
||||
@@ -935,4 +978,8 @@ def import_course(request, org, course, name):
|
||||
return render_to_response('import.html', {
|
||||
'context_course': course_module,
|
||||
'active_tab': 'import',
|
||||
'successful_import_redirect_url' : reverse('course_index', args=[
|
||||
course_module.location.org,
|
||||
course_module.location.course,
|
||||
course_module.location.name])
|
||||
})
|
||||
|
||||
@@ -74,6 +74,9 @@ $(document).ready(function() {
|
||||
handle: 'header .drag-handle',
|
||||
update: onSectionReordered
|
||||
});
|
||||
|
||||
$('.new-course-button').bind('click', addNewCourse);
|
||||
|
||||
});
|
||||
|
||||
function showImportSubmit(e) {
|
||||
@@ -81,6 +84,7 @@ function showImportSubmit(e) {
|
||||
$('.file-name-block').show();
|
||||
$('.import .choose-file-button').hide();
|
||||
$('.submit-button').show();
|
||||
$('.progress').show();
|
||||
}
|
||||
|
||||
function syncReleaseDate(e) {
|
||||
@@ -449,6 +453,7 @@ function addNewSection(e) {
|
||||
$newSection.find('.new-section-name-cancel').bind('click', cancelNewSection);
|
||||
}
|
||||
|
||||
|
||||
function saveNewSection(e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -473,6 +478,48 @@ function cancelNewSection(e) {
|
||||
$(this).parents('section.new-section').remove();
|
||||
}
|
||||
|
||||
|
||||
function addNewCourse(e) {
|
||||
e.preventDefault();
|
||||
var $newCourse = $($('#new-course-template').html());
|
||||
$('.new-course-button').after($newCourse);
|
||||
$newCourse.find('.new-course-org').focus().select();
|
||||
$newCourse.find('.new-course-save').bind('click', saveNewCourse);
|
||||
$newCourse.find('.new-course-cancel').bind('click', cancelNewCourse);
|
||||
}
|
||||
|
||||
function saveNewCourse(e) {
|
||||
e.preventDefault();
|
||||
|
||||
template = $(this).data('template');
|
||||
|
||||
org = $(this).prevAll('.new-course-org').val();
|
||||
number = $(this).prevAll('.new-course-number').val();
|
||||
display_name = $(this).prevAll('.new-course-name').val();
|
||||
|
||||
if (org == '' || number == '' || display_name == ''){
|
||||
alert('You must specify all fields in order to create a new course.')
|
||||
}
|
||||
|
||||
$.post('/create_new_course',
|
||||
{ 'template' : template,
|
||||
'org' : org,
|
||||
'number' : number,
|
||||
'display_name': display_name,
|
||||
},
|
||||
function(data) {
|
||||
if (data.id != undefined)
|
||||
location.reload();
|
||||
else if (data.ErrMsg != undefined)
|
||||
alert(data.ErrMsg);
|
||||
});
|
||||
}
|
||||
|
||||
function cancelNewCourse(e) {
|
||||
e.preventDefault();
|
||||
$(this).parents('section.new-course').remove();
|
||||
}
|
||||
|
||||
function addNewSubsection(e) {
|
||||
e.preventDefault();
|
||||
var $section = $(this).closest('.courseware-section');
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<script src="${static.url('js/vendor/jquery.cookie.js')}"></script>
|
||||
<script src="${static.url('js/vendor/jquery.leanModal.min.js')}"></script>
|
||||
<script src="${static.url('js/vendor/jquery.tablednd.js')}"></script>
|
||||
<script src="http://malsup.github.com/jquery.form.js"></script>
|
||||
<script src="${static.url('js/vendor/jquery.form.js')}"></script>
|
||||
<script type="text/javascript">
|
||||
document.write('\x3Cscript type="text/javascript" src="' +
|
||||
document.location.protocol + '//www.youtube.com/player_api">\x3C/script>');
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<%inherit file="base.html" />
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%! from django.core.urlresolvers import reverse %>
|
||||
<%block name="title">Import</%block>
|
||||
<%block name="bodyclass">import</%block>
|
||||
@@ -21,6 +23,10 @@
|
||||
<p class="file-name-block"><span class="file-name"></span><a href="#" class="choose-file-button-inline">change</a></p>
|
||||
<input type="file" name="course-data" class="file-input">
|
||||
<input type="submit" value="Replace my course with the one above" class="submit-button">
|
||||
<div class="progress" style="position:relative; margin-top:5px; width:250px; height:15px; border: 1px solid #ddd; padding: 1px; border-radius: 3px; display:none;">
|
||||
<div class="bar" style="background-color: #B4F5B4; width:0%; height:10px; border-radius: 3px;"></div>
|
||||
<div class="percent" style="margin-top:5px;">0%</div>
|
||||
</div>
|
||||
</form>
|
||||
</article>
|
||||
</div>
|
||||
@@ -28,7 +34,6 @@
|
||||
</%block>
|
||||
|
||||
<%block name="jsextra">
|
||||
<script src="//malsup.github.com/jquery.form.js"></script>
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
@@ -49,7 +54,12 @@ $('form').ajaxForm({
|
||||
percent.html(percentVal);
|
||||
},
|
||||
complete: function(xhr) {
|
||||
status.html(xhr.responseText);
|
||||
if (xhr.status == 200) {
|
||||
alert('Your import has been successful.');
|
||||
window.location = '${successful_import_redirect_url}';
|
||||
}
|
||||
else
|
||||
alert('Your import has failed.\n\n' + xhr.responseText);
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -2,13 +2,28 @@
|
||||
<%block name="bodyclass">index</%block>
|
||||
<%block name="title">Courses</%block>
|
||||
|
||||
<%block name="content">
|
||||
<%block name="header_extras">
|
||||
<script type="text/template" id="new-course-template">
|
||||
<section class="courseware-section new-course">
|
||||
<header>
|
||||
<div class="item-details">
|
||||
<h3 class="course-info">
|
||||
<input type="text" placeholder="Organization" class="new-course-org" />
|
||||
<input type="text" placeholder="Course Number" class="new-course-number" />
|
||||
<input type="text" placeholder="Course Name" class="new-course-name" />
|
||||
<a href="#" class="new-course-save" data-template="${new_course_template}">Save</a><a href="#" class="new-course-cancel">Cancel</a></h3>
|
||||
</div>
|
||||
</header>
|
||||
</section>
|
||||
</script>
|
||||
</%block>
|
||||
|
||||
<%block name="content">
|
||||
<div class="main-wrapper">
|
||||
<div class="inner-wrapper">
|
||||
<h1>My Courses</h1>
|
||||
<article class="my-classes">
|
||||
<a href="#" class="new-course-button wip-box"><span class="plus-icon"></span> New Course</a>
|
||||
<a href="#" class="new-course-button"><span class="plus-icon"></span> New Course</a>
|
||||
<ul class="class-list">
|
||||
%for course, url in courses:
|
||||
<li>
|
||||
|
||||
@@ -16,8 +16,7 @@ urlpatterns = ('',
|
||||
url(r'^create_draft$', 'contentstore.views.create_draft', name='create_draft'),
|
||||
url(r'^publish_draft$', 'contentstore.views.publish_draft', name='publish_draft'),
|
||||
url(r'^unpublish_unit$', 'contentstore.views.unpublish_unit', name='unpublish_unit'),
|
||||
|
||||
|
||||
url(r'^create_new_course', 'contentstore.views.create_new_course', name='create_new_course'),
|
||||
|
||||
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<name>[^/]+)$',
|
||||
'contentstore.views.course_index', name='course_index'),
|
||||
|
||||
Reference in New Issue
Block a user