Commit 6d6e144c by cahrens

Urls working.

parent 10ac7e04
...@@ -19,7 +19,7 @@ def i_see_default_checklists(step): ...@@ -19,7 +19,7 @@ def i_see_default_checklists(step):
assert_true(checklists[0].text.endswith('Getting Started With Studio')) assert_true(checklists[0].text.endswith('Getting Started With Studio'))
assert_true(checklists[1].text.endswith('Draft a Rough Course Outline')) assert_true(checklists[1].text.endswith('Draft a Rough Course Outline'))
assert_true(checklists[2].text.endswith("Explore edX\'s Support Tools")) assert_true(checklists[2].text.endswith("Explore edX\'s Support Tools"))
assert_true(checklists[3].text.endswith('Draft your Course Introduction')) assert_true(checklists[3].text.endswith('Draft Your Course About Page'))
@step('I can check and uncheck tasks in a checklist$') @step('I can check and uncheck tasks in a checklist$')
......
...@@ -2,6 +2,7 @@ from django.conf import settings ...@@ -2,6 +2,7 @@ from django.conf import settings
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from django.core.urlresolvers import reverse
DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_tab', 'course_info'] DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_tab', 'course_info']
...@@ -158,3 +159,23 @@ def update_item(location, value): ...@@ -158,3 +159,23 @@ def update_item(location, value):
get_modulestore(location).delete_item(location) get_modulestore(location).delete_item(location)
else: else:
get_modulestore(location).update_item(location, value) get_modulestore(location).update_item(location, value)
def get_url_reverse(course_page_name, course):
# TODO: document and write unit tests
url_name = getattr(CoursePageNames, course_page_name, None)
ctx_loc = course.location
if CoursePageNames.ManageUsers == url_name:
return reverse(url_name, kwargs={"location": ctx_loc})
elif url_name in [CoursePageNames.SettingsDetails, CoursePageNames.SettingsGrading, CoursePageNames.CourseOutline]:
return reverse(url_name, kwargs={'org' : ctx_loc.org, 'course' : ctx_loc.course, 'name': ctx_loc.name})
else:
return course_page_name
class CoursePageNames:
ManageUsers = "manage_users"
SettingsDetails = "settings_details"
SettingsGrading = "settings_grading"
CourseOutline = "course_index"
...@@ -51,7 +51,7 @@ from xmodule.contentstore.content import StaticContent ...@@ -51,7 +51,7 @@ from xmodule.contentstore.content import StaticContent
from auth.authz import is_user_in_course_group_role, get_users_in_course_group_by_role from auth.authz import is_user_in_course_group_role, get_users_in_course_group_by_role
from auth.authz import get_user_by_email, add_user_to_course_group, remove_user_from_course_group from auth.authz import get_user_by_email, add_user_to_course_group, remove_user_from_course_group
from auth.authz import INSTRUCTOR_ROLE_NAME, STAFF_ROLE_NAME, create_all_course_groups from auth.authz import INSTRUCTOR_ROLE_NAME, STAFF_ROLE_NAME, create_all_course_groups
from .utils import get_course_location_for_item, get_lms_link_for_item, compute_unit_state, get_date_display, UnitState, get_course_for_item from .utils import get_course_location_for_item, get_lms_link_for_item, compute_unit_state, get_date_display, UnitState, get_course_for_item, get_url_reverse
from xmodule.modulestore.xml_importer import import_from_xml from xmodule.modulestore.xml_importer import import_from_xml
from contentstore.course_info_model import get_course_updates,\ from contentstore.course_info_model import get_course_updates,\
...@@ -141,10 +141,7 @@ def index(request): ...@@ -141,10 +141,7 @@ def index(request):
return render_to_response('index.html', { return render_to_response('index.html', {
'new_course_template': Location('i4x', 'edx', 'templates', 'course', 'Empty'), 'new_course_template': Location('i4x', 'edx', 'templates', 'course', 'Empty'),
'courses': [(course.display_name, 'courses': [(course.display_name,
reverse('course_index', args=[ get_url_reverse('CourseOutline', course),
course.location.org,
course.location.course,
course.location.name]),
get_lms_link_for_item(course.location, course_id=course.location.course_id)) get_lms_link_for_item(course.location, course_id=course.location.course_id))
for course in courses], for course in courses],
'user': request.user, 'user': request.user,
...@@ -1308,11 +1305,12 @@ def get_checklists(request, org, course, name): ...@@ -1308,11 +1305,12 @@ def get_checklists(request, org, course, name):
course_module.checklists = template_module.checklists course_module.checklists = template_module.checklists
modulestore.update_metadata(location, own_metadata(course_module)) modulestore.update_metadata(location, own_metadata(course_module))
checklists = course_module.checklists
create_checklist_action_urls(checklists, course_module)
return render_to_response('checklists.html', return render_to_response('checklists.html',
{ {
'context_course': course_module, 'context_course': course_module,
'checklists' : course_module.checklists 'checklists' : checklists
}) })
...@@ -1337,14 +1335,23 @@ def update_checklist(request, org, course, name, checklist_index=None): ...@@ -1337,14 +1335,23 @@ def update_checklist(request, org, course, name, checklist_index=None):
modified_checklist = json.loads(request.body) modified_checklist = json.loads(request.body)
course_module.checklists[int(checklist_index)] = modified_checklist course_module.checklists[int(checklist_index)] = modified_checklist
modulestore.update_metadata(location, own_metadata(course_module)) modulestore.update_metadata(location, own_metadata(course_module))
create_checklist_action_urls([modified_checklist], course_module)
return HttpResponse(json.dumps(modified_checklist), mimetype="application/json") return HttpResponse(json.dumps(modified_checklist), mimetype="application/json")
else: else:
return HttpResponseBadRequest("Could not save checklist state because the checklist index was out of range or unspecified.", return HttpResponseBadRequest("Could not save checklist state because the checklist index was out of range or unspecified.",
content_type="text/plain") content_type="text/plain")
elif request.method == 'GET': elif request.method == 'GET':
# In the JavaScript view initialize method, we do a fetch to get all the checklists. # In the JavaScript view initialize method, we do a fetch to get all the checklists.
return HttpResponse(json.dumps(course_module.checklists), mimetype="application/json") checklists = course_module.checklists
create_checklist_action_urls(checklists, course_module)
return HttpResponse(json.dumps(checklists), mimetype="application/json")
def create_checklist_action_urls(checklists, course_module):
# Expand action names to their URLs.
for checklist in checklists:
for item in checklist.get('items'):
item['action_url'] = get_url_reverse(item.get('action_url'), course_module)
@login_required @login_required
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -1539,10 +1546,7 @@ def import_course(request, org, course, name): ...@@ -1539,10 +1546,7 @@ def import_course(request, org, course, name):
return render_to_response('import.html', { return render_to_response('import.html', {
'context_course': course_module, 'context_course': course_module,
'active_tab': 'import', 'active_tab': 'import',
'successful_import_redirect_url': reverse('course_index', args=[ 'successful_import_redirect_url': get_url_reverse('CourseOutline', course_module)
course_module.location.org,
course_module.location.course,
course_module.location.name])
}) })
......
...@@ -45,7 +45,8 @@ ...@@ -45,7 +45,8 @@
<% if (item['action_text'] !== '' && item['action_url'] !== '') { %> <% if (item['action_text'] !== '' && item['action_url'] !== '') { %>
<ul class="list-actions task-actions"> <ul class="list-actions task-actions">
<li> <li>
<a href="<%= item['action_url'] %>" class="action action-primary"><%= item['action_text'] %></a> <a href="<%= item['action_url'] %>" rel="external" class="action action-primary"
title="This link will open in a new browser window/tab"><%= item['action_text'] %></a>
</li> </li>
</ul> </ul>
<% } %> <% } %>
......
...@@ -5,7 +5,8 @@ CMS.Views.Checklists = Backbone.View.extend({ ...@@ -5,7 +5,8 @@ CMS.Views.Checklists = Backbone.View.extend({
events : { events : {
'click .course-checklist .checklist-title' : "toggleChecklist", 'click .course-checklist .checklist-title' : "toggleChecklist",
'click .course-checklist .task input' : "toggleTask" 'click .course-checklist .task input' : "toggleTask",
'click a[rel="external"]' : "openInNewTab"
}, },
initialize : function() { initialize : function() {
...@@ -60,7 +61,7 @@ CMS.Views.Checklists = Backbone.View.extend({ ...@@ -60,7 +61,7 @@ CMS.Views.Checklists = Backbone.View.extend({
}, },
toggleChecklist : function(e) { toggleChecklist : function(e) {
(e).preventDefault(); e.preventDefault();
$(e.target).closest('.course-checklist').toggleClass('is-collapsed'); $(e.target).closest('.course-checklist').toggleClass('is-collapsed');
}, },
...@@ -84,6 +85,11 @@ CMS.Views.Checklists = Backbone.View.extend({ ...@@ -84,6 +85,11 @@ CMS.Views.Checklists = Backbone.View.extend({
}, },
error : CMS.ServerError error : CMS.ServerError
}); });
},
openInNewTab : function(e) {
e.preventDefault();
window.open($(e.target).attr('href'));
} }
}); });
\ No newline at end of file
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
<ul> <ul>
<li class="nav-item nav-course-tools-import"><a href="${reverse('import_course', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}">Import</a></li> <li class="nav-item nav-course-tools-import"><a href="${reverse('import_course', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}">Import</a></li>
<li class="nav-item nav-course-tools-export"><a href="${reverse('export_course', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}">Export</a></li> <li class="nav-item nav-course-tools-export"><a href="${reverse('export_course', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}">Export</a></li>
<li class="nav-item nav-course-tools-checklists"><a href="${reverse('checklists', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}">Tasks &amp; Checklists</a></li> <li class="nav-item nav-course-tools-checklists"><a href="${reverse('checklists', kwargs=dict(org=ctx_loc.org, course=ctx_loc.course, name=ctx_loc.name))}">Checklists</a></li>
</ul> </ul>
</div> </div>
</div> </div>
......
from django.conf import settings from django.conf import settings
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from . import one_time_startup
# Uncomment the next two lines to enable the admin: # Uncomment the next two lines to enable the admin:
# from django.contrib import admin # from django.contrib import admin
...@@ -44,8 +43,8 @@ urlpatterns = ('', ...@@ -44,8 +43,8 @@ urlpatterns = ('',
'contentstore.views.remove_user', name='remove_user'), 'contentstore.views.remove_user', name='remove_user'),
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/info/(?P<name>[^/]+)$', 'contentstore.views.course_info', name='course_info'), url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/info/(?P<name>[^/]+)$', 'contentstore.views.course_info', name='course_info'),
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course_info/updates/(?P<provided_id>.*)$', 'contentstore.views.course_info_updates', name='course_info'), url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course_info/updates/(?P<provided_id>.*)$', 'contentstore.views.course_info_updates', name='course_info'),
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/settings-details/(?P<name>[^/]+)$', 'contentstore.views.get_course_settings', name='course_settings'), url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/settings-details/(?P<name>[^/]+)$', 'contentstore.views.get_course_settings', name='settings_details'),
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/settings-grading/(?P<name>[^/]+)$', 'contentstore.views.course_config_graders_page', name='course_settings'), url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/settings-grading/(?P<name>[^/]+)$', 'contentstore.views.course_config_graders_page', name='settings_grading'),
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/settings-details/(?P<name>[^/]+)/section/(?P<section>[^/]+).*$', 'contentstore.views.course_settings_updates', name='course_settings'), url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/settings-details/(?P<name>[^/]+)/section/(?P<section>[^/]+).*$', 'contentstore.views.course_settings_updates', name='course_settings'),
url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/settings-grading/(?P<name>[^/]+)/(?P<grader_index>.*)$', 'contentstore.views.course_grader_updates', name='course_settings'), url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/settings-grading/(?P<name>[^/]+)/(?P<grader_index>.*)$', 'contentstore.views.course_grader_updates', name='course_settings'),
# This is the URL to initially render the course advanced settings. # This is the URL to initially render the course advanced settings.
......
...@@ -7,17 +7,17 @@ metadata: ...@@ -7,17 +7,17 @@ metadata:
"items" : [{"short_description": "Add Course Team Members", "items" : [{"short_description": "Add Course Team Members",
"long_description": "Grant your collaborators permission to edit your course so you can work together.", "long_description": "Grant your collaborators permission to edit your course so you can work together.",
"is_checked": false, "is_checked": false,
"action_url": "/manage_users/", "action_url": "ManageUsers",
"action_text": "Edit Course Team"}, "action_text": "Edit Course Team"},
{"short_description": "Set Important Dates for Your Course", {"short_description": "Set Important Dates for Your Course",
"long_description": "Establish your course's student enrollment and launch dates on the Schedule and Details page.", "long_description": "Establish your course's student enrollment and launch dates on the Schedule and Details page.",
"is_checked": false, "is_checked": false,
"action_url": "/settings-details/", "action_url": "SettingsDetails",
"action_text": "Edit Course Details &amp; Schedule"}, "action_text": "Edit Course Details &amp; Schedule"},
{"short_description": "Draft Your Course's Grading Policy", {"short_description": "Draft Your Course's Grading Policy",
"long_description": "Set up your assignment types and grading policy even if you haven't created all your assignments.", "long_description": "Set up your assignment types and grading policy even if you haven't created all your assignments.",
"is_checked": false, "is_checked": false,
"action_url": "/settings-grading/", "action_url": "SettingsGrading",
"action_text": "Edit Grading Settings"}, "action_text": "Edit Grading Settings"},
{"short_description": "Explore the Other Studio Checklists", {"short_description": "Explore the Other Studio Checklists",
"long_description": "Discover other available course authoring tools, and find help when you need it.", "long_description": "Discover other available course authoring tools, and find help when you need it.",
...@@ -29,37 +29,37 @@ metadata: ...@@ -29,37 +29,37 @@ metadata:
"items" : [{"short_description": "Create Your First Section and Subsection", "items" : [{"short_description": "Create Your First Section and Subsection",
"long_description": "Use your course outline to build your first Section and Subsection.", "long_description": "Use your course outline to build your first Section and Subsection.",
"is_checked": false, "is_checked": false,
"action_url": "/course/", "action_url": "CourseOutline",
"action_text": "Edit Course Outline"}, "action_text": "Edit Course Outline"},
{"short_description": "Set Section Release Dates", {"short_description": "Set Section Release Dates",
"long_description": "Specify the release dates for each Section in your course. Sections become visible to students on their release dates.", "long_description": "Specify the release dates for each Section in your course. Sections become visible to students on their release dates.",
"is_checked": false, "is_checked": false,
"action_url": "/course/", "action_url": "CourseOutline",
"action_text": "Edit Course Outline"}, "action_text": "Edit Course Outline"},
{"short_description": "Designate a Subsection as Graded", {"short_description": "Designate a Subsection as Graded",
"long_description": "Set a Subsection to be graded as a specific assignment type. Assignments within graded Subsections count toward a student's final grade.", "long_description": "Set a Subsection to be graded as a specific assignment type. Assignments within graded Subsections count toward a student's final grade.",
"is_checked": false, "is_checked": false,
"action_url": "/course/", "action_url": "CourseOutline",
"action_text": "Edit Course Outline"}, "action_text": "Edit Course Outline"},
{"short_description": "Reordering Course Content", {"short_description": "Reordering Course Content",
"long_description": "Use drag and drop to reorder the content in your course.", "long_description": "Use drag and drop to reorder the content in your course.",
"is_checked": false, "is_checked": false,
"action_url": "/course/", "action_url": "CourseOutline",
"action_text": "Edit Course Outline"}, "action_text": "Edit Course Outline"},
{"short_description": "Renaming Sections", {"short_description": "Renaming Sections",
"long_description": "Rename Sections by clicking the Section name from the Course Outline.", "long_description": "Rename Sections by clicking the Section name from the Course Outline.",
"is_checked": false, "is_checked": false,
"action_url": "/course/", "action_url": "CourseOutline",
"action_text": "Edit Course Outline"}, "action_text": "Edit Course Outline"},
{"short_description": "Deleting Course Content", {"short_description": "Deleting Course Content",
"long_description": "Delete Sections, Subsections, or Units you don't need anymore. Be careful, as there is no Undo function.", "long_description": "Delete Sections, Subsections, or Units you don't need anymore. Be careful, as there is no Undo function.",
"is_checked": false, "is_checked": false,
"action_url": "/course/", "action_url": "CourseOutline",
"action_text": "Edit Course Outline"}, "action_text": "Edit Course Outline"},
{"short_description": "Add an Instructor-Only Section to Your Outline", {"short_description": "Add an Instructor-Only Section to Your Outline",
"long_description": "Some course authors find using a section for unsorted, in-progress work useful. To do this, create a section and set the release date to the distant future.", "long_description": "Some course authors find using 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, "is_checked": false,
"action_url": "/course/", "action_url": "CourseOutline",
"action_text": "Edit Course Outline"}] "action_text": "Edit Course Outline"}]
}, },
{"short_description" : "Explore edX's Support Tools", {"short_description" : "Explore edX's Support Tools",
...@@ -71,35 +71,35 @@ metadata: ...@@ -71,35 +71,35 @@ metadata:
{"short_description": "Enroll in edX 101", {"short_description": "Enroll in edX 101",
"long_description": "Register for edX 101, edX's primer for course creation.", "long_description": "Register for edX 101, edX's primer for course creation.",
"is_checked": false, "is_checked": false,
"action_url": "/", "action_url": "https://edge.edx.org/courses/edX/edX101/How_to_Create_an_edX_Course/about",
"action_text": "Register for edX 101"}, "action_text": "Register for edX 101"},
{"short_description": "Download the Studio Documentation", {"short_description": "Download the Studio Documentation",
"long_description": "Download the searchable Studio reference documentation in PDF form.", "long_description": "Download the searchable Studio reference documentation in PDF form.",
"is_checked": false, "is_checked": false,
"action_url": "/", "action_url": "http://help.edge.edx.org/help/assets/8ccd409f979c8639dd463e126eb840dc67f09098/Getting_Started_with_Studio.pdf",
"action_text": "Download Documentation"}] "action_text": "Download Documentation"}]
}, },
{"short_description" : "Draft Your Course About Page", {"short_description" : "Draft Your Course About Page",
"items" : [{"short_description": "Draft a Course Description", "items" : [{"short_description": "Draft a Course Description",
"long_description": "Courses on edX have an About page that includes a course video, description, and more. Draft the text students will read before deciding to enroll in your course.", "long_description": "Courses on edX have an About page that includes a course video, description, and more. Draft the text students will read before deciding to enroll in your course.",
"is_checked": false, "is_checked": false,
"action_url": "/settings-details/", "action_url": "SettingsDetails",
"action_text": "Edit Course Details &amp; Schedule"}, "action_text": "Edit Course Schedule &amp; Details"},
{"short_description": "Add Staff Bios", {"short_description": "Add Staff Bios",
"long_description": "Showing prospective students who their instructor will be is helpful. Include staff bios on the course About page.", "long_description": "Showing prospective students who their instructor will be is helpful. Include staff bios on the course About page.",
"is_checked": false, "is_checked": false,
"action_url": "/settings-details/", "action_url": "SettingsDetails",
"action_text": "Edit Course Details &amp; Schedule"}, "action_text": "Edit Course Schedule &amp; Details"},
{"short_description": "Add Course FAQs", {"short_description": "Add Course FAQs",
"long_description": "Include a short list of frequently asked questions about your course.", "long_description": "Include a short list of frequently asked questions about your course.",
"is_checked": false, "is_checked": false,
"action_url": "/settings-details/", "action_url": "SettingsDetails",
"action_text": "Edit Course Details &amp; Schedule"}, "action_text": "Edit Course Schedule &amp; Details"},
{"short_description": "Add Course Prerequisites", {"short_description": "Add Course Prerequisites",
"long_description": "Let students know what knowledge and/or skills they should have before they enroll in your course.", "long_description": "Let students know what knowledge and/or skills they should have before they enroll in your course.",
"is_checked": false, "is_checked": false,
"action_url": "/settings-details/", "action_url": "SettingsDetails",
"action_text": "Edit Course Details &amp; Schedule"}] "action_text": "Edit Course Schedule &amp; Details"}]
} }
] ]
data: { 'textbooks' : [ ], 'wiki_slug' : null } data: { 'textbooks' : [ ], 'wiki_slug' : null }
......
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