Saving checkbox state, client template for individual checklist.
This commit is contained in:
@@ -1103,11 +1103,7 @@ def course_info_updates(request, org, course, provided_id=None):
|
||||
if not has_access(request.user, location):
|
||||
raise PermissionDenied()
|
||||
|
||||
# NB: we're setting Backbone.emulateHTTP to true on the client so everything comes as a post!!!
|
||||
if request.method == 'POST' and 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
|
||||
real_method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
|
||||
else:
|
||||
real_method = request.method
|
||||
real_method = get_request_method(request)
|
||||
|
||||
if request.method == 'GET':
|
||||
return HttpResponse(json.dumps(get_course_updates(location)), mimetype="application/json")
|
||||
@@ -1130,11 +1126,7 @@ def module_info(request, module_location):
|
||||
if not has_access(request.user, location):
|
||||
raise PermissionDenied()
|
||||
|
||||
# NB: we're setting Backbone.emulateHTTP to true on the client so everything comes as a post!!!
|
||||
if request.method == 'POST' and 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
|
||||
real_method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
|
||||
else:
|
||||
real_method = request.method
|
||||
real_method = get_request_method(request)
|
||||
|
||||
rewrite_static_links = request.GET.get('rewrite_url_links', 'True') in ['True', 'true']
|
||||
logging.debug('rewrite_static_links = {0} {1}'.format(request.GET.get('rewrite_url_links', 'False'), rewrite_static_links))
|
||||
@@ -1259,21 +1251,18 @@ def course_grader_updates(request, org, course, name, grader_index=None):
|
||||
|
||||
location = get_location_and_verify_access(request, org, course, name)
|
||||
|
||||
if request.method == 'POST' and 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
|
||||
real_method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
|
||||
else:
|
||||
real_method = request.method
|
||||
real_method = get_request_method(request)
|
||||
|
||||
if real_method == 'GET':
|
||||
# Cannot just do a get w/o knowing the course name :-(
|
||||
return HttpResponse(json.dumps(CourseGradingModel.fetch_grader(Location(['i4x', org, course, 'course', name]), grader_index)),
|
||||
return HttpResponse(json.dumps(CourseGradingModel.fetch_grader(Location(location), grader_index)),
|
||||
mimetype="application/json")
|
||||
elif real_method == "DELETE":
|
||||
# ??? Shoudl this return anything? Perhaps success fail?
|
||||
CourseGradingModel.delete_grader(Location(['i4x', org, course, 'course', name]), grader_index)
|
||||
# ??? Should this return anything? Perhaps success fail?
|
||||
CourseGradingModel.delete_grader(Location(location), grader_index)
|
||||
return HttpResponse()
|
||||
elif request.method == 'POST': # post or put, doesn't matter.
|
||||
return HttpResponse(json.dumps(CourseGradingModel.update_grader_from_json(Location(['i4x', org, course, 'course', name]), request.POST)),
|
||||
return HttpResponse(json.dumps(CourseGradingModel.update_grader_from_json(Location(location), request.POST)),
|
||||
mimetype="application/json")
|
||||
|
||||
|
||||
@@ -1289,11 +1278,7 @@ def course_advanced_updates(request, org, course, name):
|
||||
"""
|
||||
location = get_location_and_verify_access(request, org, course, name)
|
||||
|
||||
# NB: we're setting Backbone.emulateHTTP to true on the client so everything comes as a post!!!
|
||||
if request.method == 'POST' and 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
|
||||
real_method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
|
||||
else:
|
||||
real_method = request.method
|
||||
real_method = get_request_method(request)
|
||||
|
||||
if real_method == 'GET':
|
||||
return HttpResponse(json.dumps(CourseMetadata.fetch(location)), mimetype="application/json")
|
||||
@@ -1320,13 +1305,32 @@ def get_checklists(request, org, course, name):
|
||||
course_module.metadata[key] = template_module.metadata[key]
|
||||
modulestore.update_metadata(location, course_module.metadata)
|
||||
|
||||
|
||||
checklists = course_module.metadata[key]
|
||||
return render_to_response('checklists.html',
|
||||
{
|
||||
'context_course': course_module,
|
||||
'checklists' : course_module.metadata[key]
|
||||
'checklists' : checklists,
|
||||
'checklists_json' : json.dumps(checklists)
|
||||
|
||||
})
|
||||
|
||||
@login_required
|
||||
def update_checklist(request, org, course, name, checklist_index=None):
|
||||
location = get_location_and_verify_access(request, org, course, name)
|
||||
modulestore = get_modulestore(location)
|
||||
course_module = modulestore.get_item(location)
|
||||
key = "checklists"
|
||||
|
||||
real_method = get_request_method(request)
|
||||
if checklist_index is not None and (real_method == 'POST' or real_method == 'PUT'):
|
||||
modified_checklist = json.loads(request.body)
|
||||
(course_module.metadata[key])[int(checklist_index)] = modified_checklist
|
||||
modulestore.update_metadata(location, course_module.metadata)
|
||||
return HttpResponse(json.dumps(modified_checklist), mimetype="application/json")
|
||||
elif request.method == 'GET':
|
||||
# TODO: Would we ever get in this condition? Any point in having this code?
|
||||
return HttpResponse(json.dumps(course_module.metadata[key]), mimetype="application/json")
|
||||
|
||||
|
||||
@login_required
|
||||
@ensure_csrf_cookie
|
||||
@@ -1593,3 +1597,12 @@ def get_location_and_verify_access(request, org, course, name):
|
||||
raise PermissionDenied()
|
||||
|
||||
return location
|
||||
|
||||
def get_request_method(request):
|
||||
# NB: we're setting Backbone.emulateHTTP to true on the client so everything comes as a post!!!
|
||||
if request.method == 'POST' and 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
|
||||
real_method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
|
||||
else:
|
||||
real_method = request.method
|
||||
|
||||
return real_method
|
||||
|
||||
50
cms/static/client_templates/checklist.html
Normal file
50
cms/static/client_templates/checklist.html
Normal file
@@ -0,0 +1,50 @@
|
||||
<section class="course-checklist" id="<%= 'course-checklist' + checklistIndex %>">
|
||||
<% var widthPercentage = 'width:' + percentChecked + '%;'; %>
|
||||
<span class="viz viz-checklist-status"><span class="viz value viz-checklist-status-value" style="<%= widthPercentage %>">
|
||||
<span class="int"><%= percentChecked %></span>% of checklist completed</span></span>
|
||||
<header>
|
||||
<h3 class="checklist-title title-2 is-selectable" title="Collapse/Expand this Checklist">
|
||||
<i class="ss-icon ss-symbolicons-standard icon-arrow ui-toggle-expansion">▾</i>
|
||||
<%= checklistShortDescription %></h3>
|
||||
<span class="checklist-status status">
|
||||
Tasks Completed: <span class="status-count"><%= itemsChecked %></span>/<span class="status-amount"><%= items.length %></span>
|
||||
<i class="ss-icon ss-symbolicons-standard icon-confirm">✓</i>
|
||||
</span>
|
||||
</header>
|
||||
|
||||
<ul class="list list-tasks">
|
||||
<% var taskIndex = 0; %>
|
||||
<% _.each(items, function(item) { %>
|
||||
<% var checked = item['is_checked']; %>
|
||||
<li
|
||||
<% if (checked) { %>
|
||||
class="task is-completed"
|
||||
<% } else { %>
|
||||
class="task"
|
||||
<% } %>
|
||||
>
|
||||
<% var taskId = 'course-checklist' + checklistIndex + '-task' + taskIndex; %>
|
||||
<input type="checkbox" class="task-input" data-checklist="<%= checklistIndex %>" data-task="<%= taskIndex %>"
|
||||
name="<%= taskId %>" id="<%= taskId %>"
|
||||
<% if (checked) { %>
|
||||
checked="checked"
|
||||
<% } %>
|
||||
>
|
||||
<label class="task-details" for="<%= taskId %>">
|
||||
<h4 class="task-name title title-3"><%= item['short_description'] %></h4>
|
||||
<p class="task-description"><%= item['long_description'] %></p>
|
||||
</label>
|
||||
|
||||
<% if (item['action_text'] !== '' && item['action_url'] !== '') { %>
|
||||
<ul class="list-actions task-actions">
|
||||
<li>
|
||||
<a href="<%= item['action_url'] %>" class="action action-primary"><%= item['action_text'] %></a>
|
||||
</li>
|
||||
</ul>
|
||||
<% } %>
|
||||
</li>
|
||||
|
||||
<% taskIndex+=1; }) %>
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
@@ -14,10 +14,6 @@ $(document).ready(function () {
|
||||
// scopes (namely the course-info tab)
|
||||
window.$modalCover = $modalCover;
|
||||
|
||||
// Control whether template caching in local memory occurs (see template_loader.js). Caching screws up development but may
|
||||
// be a good optimization in production (it works fairly well)
|
||||
window.cachetemplates = false;
|
||||
|
||||
$body.append($modalCover);
|
||||
$newComponentItem = $('.new-component-item');
|
||||
$newComponentTypePicker = $('.new-component');
|
||||
|
||||
@@ -1 +1,16 @@
|
||||
if (!CMS.Models['Checklists']) CMS.Models.Checklists = new Object();
|
||||
CMS.Models.Checklist = Backbone.Model.extend({
|
||||
});
|
||||
|
||||
CMS.Models.ChecklistCollection = Backbone.Collection.extend({
|
||||
model : CMS.Models.Checklist,
|
||||
|
||||
parse: function(response) {
|
||||
_.each(response,
|
||||
function( element, idx ) {
|
||||
element.id = idx;
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,78 +1,79 @@
|
||||
// <!-- from https://github.com/Gazler/Underscore-Template-Loader/blob/master/index.html -->
|
||||
// TODO Figure out how to initialize w/ static views from server (don't call .load but instead inject in django as strings)
|
||||
// so this only loads the lazily loaded ones.
|
||||
(function() {
|
||||
if (typeof window.templateLoader == 'function') return;
|
||||
|
||||
var templateLoader = {
|
||||
templateVersion: "0.0.15",
|
||||
templates: {},
|
||||
loadRemoteTemplate: function(templateName, filename, callback) {
|
||||
if (!this.templates[templateName]) {
|
||||
var self = this;
|
||||
jQuery.ajax({url : filename,
|
||||
success : function(data) {
|
||||
self.addTemplate(templateName, data);
|
||||
self.saveLocalTemplates();
|
||||
callback(data);
|
||||
},
|
||||
error : function(xhdr, textStatus, errorThrown) {
|
||||
console.log(textStatus); },
|
||||
dataType : "html"
|
||||
})
|
||||
}
|
||||
else {
|
||||
callback(this.templates[templateName]);
|
||||
}
|
||||
},
|
||||
|
||||
addTemplate: function(templateName, data) {
|
||||
// is there a reason this doesn't go ahead and compile the template? _.template(data)
|
||||
// I suppose localstorage use would still req raw string rather than compiled version, but that sd work
|
||||
// if it maintains a separate cache of uncompiled ones
|
||||
this.templates[templateName] = data;
|
||||
},
|
||||
|
||||
localStorageAvailable: function() {
|
||||
try {
|
||||
// window.cachetemplates is global set in base.js to turn caching on/off
|
||||
return window.cachetemplates && 'localStorage' in window && window['localStorage'] !== null;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
saveLocalTemplates: function() {
|
||||
if (this.localStorageAvailable) {
|
||||
localStorage.setItem("templates", JSON.stringify(this.templates));
|
||||
localStorage.setItem("templateVersion", this.templateVersion);
|
||||
}
|
||||
},
|
||||
|
||||
loadLocalTemplates: function() {
|
||||
if (this.localStorageAvailable) {
|
||||
var templateVersion = localStorage.getItem("templateVersion");
|
||||
if (templateVersion && templateVersion == this.templateVersion) {
|
||||
var templates = localStorage.getItem("templates");
|
||||
if (templates) {
|
||||
templates = JSON.parse(templates);
|
||||
for (var x in templates) {
|
||||
if (!this.templates[x]) {
|
||||
this.addTemplate(x, templates[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
localStorage.removeItem("templates");
|
||||
localStorage.removeItem("templateVersion");
|
||||
}
|
||||
}
|
||||
}
|
||||
(function () {
|
||||
if (typeof window.templateLoader == 'function') return;
|
||||
|
||||
var templateLoader = {
|
||||
templateVersion: "0.0.15",
|
||||
templates: {},
|
||||
// Control whether template caching in local memory occurs. Caching screws up development but may
|
||||
// be a good optimization in production (it works fairly well).
|
||||
cacheTemplates: false,
|
||||
loadRemoteTemplate: function (templateName, filename, callback) {
|
||||
if (!this.templates[templateName]) {
|
||||
var self = this;
|
||||
jQuery.ajax({url: filename,
|
||||
success: function (data) {
|
||||
self.addTemplate(templateName, data);
|
||||
self.saveLocalTemplates();
|
||||
callback(data);
|
||||
},
|
||||
error: function (xhdr, textStatus, errorThrown) {
|
||||
console.log(textStatus);
|
||||
},
|
||||
dataType: "html"
|
||||
})
|
||||
}
|
||||
else {
|
||||
callback(this.templates[templateName]);
|
||||
}
|
||||
},
|
||||
|
||||
addTemplate: function (templateName, data) {
|
||||
// is there a reason this doesn't go ahead and compile the template? _.template(data)
|
||||
// I suppose localstorage use would still req raw string rather than compiled version, but that sd work
|
||||
// if it maintains a separate cache of uncompiled ones
|
||||
this.templates[templateName] = data;
|
||||
},
|
||||
|
||||
localStorageAvailable: function () {
|
||||
try {
|
||||
return this.cacheTemplates && 'localStorage' in window && window['localStorage'] !== null;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
saveLocalTemplates: function () {
|
||||
if (this.localStorageAvailable()) {
|
||||
localStorage.setItem("templates", JSON.stringify(this.templates));
|
||||
localStorage.setItem("templateVersion", this.templateVersion);
|
||||
}
|
||||
},
|
||||
|
||||
loadLocalTemplates: function () {
|
||||
if (this.localStorageAvailable()) {
|
||||
var templateVersion = localStorage.getItem("templateVersion");
|
||||
if (templateVersion && templateVersion == this.templateVersion) {
|
||||
var templates = localStorage.getItem("templates");
|
||||
if (templates) {
|
||||
templates = JSON.parse(templates);
|
||||
for (var x in templates) {
|
||||
if (!this.templates[x]) {
|
||||
this.addTemplate(x, templates[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
localStorage.removeItem("templates");
|
||||
localStorage.removeItem("templateVersion");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
templateLoader.loadLocalTemplates();
|
||||
window.templateLoader = templateLoader;
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -5,15 +5,52 @@ CMS.Views.Checklists = Backbone.View.extend({
|
||||
|
||||
events : {
|
||||
'click .course-checklist .checklist-title' : "toggleChecklist",
|
||||
'click .course-checklist .task label' : "toggleTask",
|
||||
'click .demo-checklistviz' : "demoUpdateProgress"
|
||||
'click .course-checklist .task input' : "toggleTask"
|
||||
},
|
||||
|
||||
initialize : function() {
|
||||
// adding class and title needs to happen in HTML
|
||||
// $('.course-checklist .checklist-title').each(function(e){
|
||||
// $(this).addClass('is-selectable').attr('title','Collapse/Expand this Checklist').bind('click', this.toggleChecklist);
|
||||
// });
|
||||
var self = this;
|
||||
// instantiates an editor template for each update in the collection
|
||||
window.templateLoader.loadRemoteTemplate("checklist",
|
||||
"/static/client_templates/checklist.html",
|
||||
function (raw_template) {
|
||||
self.template = _.template(raw_template);
|
||||
self.render();
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
// catch potential outside call before template loaded
|
||||
if (!this.template) return this;
|
||||
|
||||
this.$el.empty();
|
||||
|
||||
var self = this;
|
||||
_.each(this.collection.models,
|
||||
function(checklist, index) {
|
||||
self.$el.append(self.renderTemplate(checklist, index));
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
renderTemplate: function (checklist, index) {
|
||||
var checklistItems = checklist.attributes['items'];
|
||||
var itemsChecked = 0;
|
||||
_.each(checklistItems,
|
||||
function(checklist) {
|
||||
if (checklist['is_checked']) {
|
||||
itemsChecked +=1;
|
||||
}
|
||||
});
|
||||
var percentChecked = Math.round((itemsChecked/checklistItems.length)*100);
|
||||
return this.template({
|
||||
checklistIndex : index,
|
||||
checklistShortDescription : checklist.attributes['short_description'],
|
||||
items: checklistItems,
|
||||
itemsChecked: itemsChecked,
|
||||
percentChecked: percentChecked});
|
||||
},
|
||||
|
||||
toggleChecklist : function(e) {
|
||||
@@ -22,27 +59,25 @@ CMS.Views.Checklists = Backbone.View.extend({
|
||||
},
|
||||
|
||||
toggleTask : function (e) {
|
||||
$(e.target).closest('.task').toggleClass('is-completed');
|
||||
},
|
||||
var self = this;
|
||||
|
||||
// TODO: remove
|
||||
demoUpdateProgress : function(e) {
|
||||
(e).preventDefault();
|
||||
$('#course-checklist0 .viz-checklist-status .viz-checklist-status-value').css('width','25%');
|
||||
},
|
||||
var completed = 'is-completed';
|
||||
var $checkbox = $(e.target);
|
||||
var $task = $checkbox.closest('.task');
|
||||
$task.toggleClass(completed);
|
||||
|
||||
// TODO: not used. In-progress update checklist progress (based on checkbox check/uncheck events)
|
||||
updateChecklistProgress : function(e) {
|
||||
var $statusCount = this.$el.closest('.course-checklist').find('.status-count');
|
||||
var $statusAmount = this.$el.closest('.course-checklist').find('.status-amount');
|
||||
|
||||
if (this.$el.attr('checked')) {
|
||||
console.log('adding');
|
||||
}
|
||||
|
||||
else {
|
||||
console.log('subtracting');
|
||||
}
|
||||
var checklist_index = $checkbox.data('checklist');
|
||||
var task_index = $checkbox.data('task');
|
||||
var model = this.collection.at(checklist_index);
|
||||
model.attributes.items[task_index].is_checked = $task.hasClass(completed);
|
||||
model.save({},
|
||||
{
|
||||
success : function() {
|
||||
var updatedTemplate = self.renderTemplate(model, checklist_index);
|
||||
self.$el.find('#course-checklist'+checklist_index).first().replaceWith(updatedTemplate);
|
||||
},
|
||||
error : CMS.ServerError
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,21 +1,28 @@
|
||||
<%inherit file="base.html" />
|
||||
<%! from django.core.urlresolvers import reverse %>
|
||||
<%block name="title">Course Checklists</%block>
|
||||
<%block name="bodyclass">is-signedin course uxdesign checklists</%block>
|
||||
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%block name="jsextra">
|
||||
|
||||
<script type="text/javascript" src="${static.url('js/template_loader.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/checklists_view.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/models/checklists.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/server_error.js')}"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
// TODO: do a fetch instead of passing text into constructor.
|
||||
var checklistCollection = new CMS.Models.ChecklistCollection(${checklists_json | n}, {parse: true});
|
||||
checklistCollection.url = "${reverse('checklists_updates', kwargs=dict(org=context_course.location.org, course=context_course.location.course, name=context_course.location.name))}";
|
||||
|
||||
var editor = new CMS.Views.Checklists({
|
||||
el: $('.course-checklists')
|
||||
el: $('.course-checklists'),
|
||||
collection: checklistCollection
|
||||
});
|
||||
|
||||
// No need to call render yet-- state is not being injected.
|
||||
// editor.render();
|
||||
editor.render();
|
||||
|
||||
});
|
||||
|
||||
@@ -42,46 +49,6 @@
|
||||
<article class="content-primary" role="main">
|
||||
<form id="course-checklists" class="course-checklists" method="post" action="">
|
||||
<h2 class="title title-3 sr">Current Checklists</h2>
|
||||
|
||||
|
||||
% for checklist in checklists:
|
||||
<section class="course-checklist" id=${'course-checklist' + str(loop.index)}>
|
||||
<span class="viz viz-checklist-status"><span class="viz value viz-checklist-status-value"><span class="int">0</span>% of checklist completed</span></span>
|
||||
<header>
|
||||
<h3 class="checklist-title title-2 is-selectable" title="Collapse/Expand this Checklist">
|
||||
<i class="ss-icon ss-symbolicons-standard icon-arrow ui-toggle-expansion">▾</i>
|
||||
${checklist['short_description']}</h3>
|
||||
<span class="checklist-status status">
|
||||
Tasks Completed: <span class="status-count">0</span>/<span class="status-amount">4</span>
|
||||
<i class="ss-icon ss-symbolicons-standard icon-confirm">✓</i>
|
||||
</span>
|
||||
</header>
|
||||
|
||||
<ul class="list list-tasks">
|
||||
|
||||
% for item in checklist['items']:
|
||||
<li class="task">
|
||||
<input type="checkbox" class="task-input" name=${'course-checklist' + str(loop.parent.index) + '-task' + str(loop.index)}
|
||||
id=${'course-checklist' + str(loop.parent.index) + '-task' + str(loop.index)}
|
||||
value=${item['is_checked']}>
|
||||
<label class="task-details" for=${'course-checklist' + str(loop.parent.index) + '-task' + str(loop.index)}>
|
||||
<h4 class="task-name title title-3">${item['short_description']}</h4>
|
||||
<p class="task-description">${item['long_description']}</p>
|
||||
</label>
|
||||
|
||||
% if item['action_text'] is not '' and item['action_url'] is not '':
|
||||
<ul class="list-actions task-actions">
|
||||
<li>
|
||||
<a href=${item['action_url']} class="action action-primary">${item['action_text']}</a>
|
||||
</li>
|
||||
</ul>
|
||||
% endif
|
||||
</li>
|
||||
% endfor
|
||||
|
||||
</ul>
|
||||
</section>
|
||||
% endfor
|
||||
</form>
|
||||
</article>
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ urlpatterns = ('',
|
||||
# User creation and updating views
|
||||
urlpatterns += (
|
||||
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/checklists/(?P<name>[^/]+)$', 'contentstore.views.get_checklists', name='checklists'),
|
||||
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/checklists/(?P<name>[^/]+)/update(/)?(?P<checklist_index>.+)?.*$',
|
||||
'contentstore.views.update_checklist', name='checklists_updates'),
|
||||
url(r'^howitworks$', 'contentstore.views.howitworks', name='howitworks'),
|
||||
url(r'^signup$', 'contentstore.views.signup', name='signup'),
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ metadata:
|
||||
"long_description": "They'll help you learn the other course authoring tools available to you, and will also help you find help when you need it.",
|
||||
"is_checked": false,
|
||||
"action_url": "",
|
||||
"action_text": ""}],
|
||||
"completed" : false},
|
||||
{"short_description" : "Draft a Rough Course Outline",
|
||||
"items" : [{"short_description": "Create your first Section and Subsection",
|
||||
"action_text": ""}]
|
||||
},
|
||||
{"short_description" : "Draft a Rough Course Outline",
|
||||
"items" : [{"short_description": "Create your first Section and Subsection",
|
||||
"long_description": "Walk through the mechanics of building your course's first section and subsection through your course outline to start.",
|
||||
"is_checked": false,
|
||||
"action_url": "/course/",
|
||||
@@ -60,10 +60,10 @@ metadata:
|
||||
"long_description": "Some course authors find creating a section for unsorted, in-progress work useful. To do this, create a section and set the release date to the distant future.",
|
||||
"is_checked": false,
|
||||
"action_url": "/course/",
|
||||
"action_text": "Edit in Course Outline"}],
|
||||
"completed" : false},
|
||||
{"short_description" : "Explore edX's Support Tools",
|
||||
"items" : [{"short_description": "Explore the Studio Help Forum",
|
||||
"action_text": "Edit in Course Outline"}]
|
||||
},
|
||||
{"short_description" : "Explore edX's Support Tools",
|
||||
"items" : [{"short_description": "Explore the Studio Help Forum",
|
||||
"long_description": "Access the Studio Help forum from the menu that appears when you click your user name in the top right corner of Studio.",
|
||||
"is_checked": false,
|
||||
"action_url": "http://help.edge.edx.org/",
|
||||
@@ -77,10 +77,10 @@ metadata:
|
||||
"long_description": "View the searchable Studio documentation to find answers to your questions or information about how to do specific tasks. Once you download the PDF, you can view it offline.",
|
||||
"is_checked": false,
|
||||
"action_url": "/",
|
||||
"action_text": "Download Documentation"}],
|
||||
"completed" : false},
|
||||
{"short_description" : "Draft your Course Introduction",
|
||||
"items" : [{"short_description": "Drafting a Course Description",
|
||||
"action_text": "Download Documentation"}]
|
||||
},
|
||||
{"short_description" : "Draft your Course Introduction",
|
||||
"items" : [{"short_description": "Drafting a Course Description",
|
||||
"long_description": "Courses on edX each have their own introduction page, including a course video, description, and more. Draft the introduction students will read before deciding to enroll in your course.",
|
||||
"is_checked": false,
|
||||
"action_url": "/settings-details/",
|
||||
@@ -99,8 +99,8 @@ metadata:
|
||||
"long_description": "Before a student jumps into a course without the necessary preparation, we'd like them to understand the prerequisites that will make them more likely to succeed.",
|
||||
"is_checked": false,
|
||||
"action_url": "/settings-details/",
|
||||
"action_text": "Edit Course Details & Schedule"}],
|
||||
"completed" : false}
|
||||
]
|
||||
"action_text": "Edit Course Details & Schedule"}]
|
||||
}
|
||||
]
|
||||
data: { 'textbooks' : [ ], 'wiki_slug' : null }
|
||||
children: []
|
||||
|
||||
Reference in New Issue
Block a user