fix up styling by reusing existing CSS class names. Also refactor some code regarding the management of static_tabs so that it's in the course as course contains references to static_tabs in the current data model
This commit is contained in:
@@ -33,6 +33,31 @@ def get_course_location_for_item(location):
|
||||
|
||||
return location
|
||||
|
||||
def get_course_for_item(location):
|
||||
'''
|
||||
cdodge: for a given Xmodule, return the course that it belongs to
|
||||
NOTE: This makes a lot of assumptions about the format of the course location
|
||||
Also we have to assert that this module maps to only one course item - it'll throw an
|
||||
assert if not
|
||||
'''
|
||||
item_loc = Location(location)
|
||||
|
||||
# @hack! We need to find the course location however, we don't
|
||||
# know the 'name' parameter in this context, so we have
|
||||
# to assume there's only one item in this query even though we are not specifying a name
|
||||
course_search_location = ['i4x', item_loc.org, item_loc.course, 'course', None]
|
||||
courses = modulestore().get_items(course_search_location)
|
||||
|
||||
# make sure we found exactly one match on this above course search
|
||||
found_cnt = len(courses)
|
||||
if found_cnt == 0:
|
||||
raise BaseException('Could not find course at {0}'.format(course_search_location))
|
||||
|
||||
if found_cnt > 1:
|
||||
raise BaseException('Found more than one course at {0}. There should only be one!!! Dump = {1}'.format(course_search_location, courses))
|
||||
|
||||
return courses[0]
|
||||
|
||||
|
||||
def get_lms_link_for_item(location, preview=False):
|
||||
location = Location(location)
|
||||
|
||||
@@ -55,7 +55,7 @@ from cache_toolbox.core import set_cached_content, get_cached_content, del_cache
|
||||
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 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
|
||||
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 xmodule.templates import all_templates
|
||||
from xmodule.modulestore.xml_importer import import_from_xml
|
||||
@@ -68,6 +68,9 @@ COMPONENT_TYPES = ['customtag', 'discussion', 'html', 'problem', 'video']
|
||||
|
||||
DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_tab', 'course_info']
|
||||
|
||||
# cdodge: these are categories which should not be parented, they are detached from the hierarchy
|
||||
DETACHED_CATEGORIES = ['about', 'static_tab', 'course_info']
|
||||
|
||||
|
||||
def _modulestore(location):
|
||||
"""
|
||||
@@ -616,6 +619,17 @@ def save_item(request):
|
||||
# commit to datastore
|
||||
store.update_metadata(item_location, existing_item.metadata)
|
||||
|
||||
# cdodge: special case logic for updating static_tabs
|
||||
# unfortunately tabs are enumerated in the course policy data structure, so if we change the display name of
|
||||
# the tab, we need to update the course policy (which has a nice .tabs property on it)
|
||||
item_loc = Location(item_location)
|
||||
if item_loc.category == 'static_tab':
|
||||
# VS[compat] Rework when we can stop having to support tabs lists in the policy
|
||||
tag_module = store.get_item(item_location)
|
||||
course = get_course_for_item(item_location)
|
||||
course.update_tab_reference(tag_module)
|
||||
modulestore('direct').update_metadata(course.location, course.metadata)
|
||||
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
@@ -689,7 +703,16 @@ def clone_item(request):
|
||||
new_item.metadata['display_name'] = display_name
|
||||
|
||||
_modulestore(template).update_metadata(new_item.location.url(), new_item.own_metadata)
|
||||
_modulestore(parent.location).update_children(parent_location, parent.definition.get('children', []) + [new_item.location.url()])
|
||||
|
||||
if new_item.location.category not in DETACHED_CATEGORIES:
|
||||
_modulestore(parent.location).update_children(parent_location, parent.definition.get('children', []) + [new_item.location.url()])
|
||||
elif new_item.location.category == 'static_tab':
|
||||
# static tabs - in our data model - are described in the course policy
|
||||
# VS[compat]: Rework when we can stop having to support tabs lists in the policy
|
||||
if parent.location.category != 'course':
|
||||
raise BaseException('adding a new static_tab must be on a course object')
|
||||
parent.add_tab_reference(new_item)
|
||||
_modulestore(parent.location).update_metadata(parent.location.url(), parent.metadata)
|
||||
|
||||
return HttpResponse(json.dumps({'id': dest_location.url()}))
|
||||
|
||||
@@ -877,7 +900,7 @@ def edit_tabs(request, org, course, coursename):
|
||||
|
||||
static_tabs = modulestore('direct').get_items(static_tabs_loc)
|
||||
|
||||
# import pudb; pudb.set_trace()
|
||||
logging.debug('tabs in policy = %s', course_item.tabs)
|
||||
|
||||
components = [
|
||||
static_tab.location.url()
|
||||
@@ -995,6 +1018,17 @@ def create_new_course(request):
|
||||
# set a default start date to now
|
||||
new_course.metadata['start'] = stringify_time(time.gmtime())
|
||||
|
||||
# set up the default tabs
|
||||
# I've added this because when we add static tabs, the LMS either expects a None for the tabs list or
|
||||
# at least a list populated with the minimal times
|
||||
# @TODO: I don't like the fact that the presentation tier is away of these data related constraints, let's find a better
|
||||
# place for this. Also rather than using a simple list of dictionaries a nice class model would be helpful here
|
||||
new_course.tabs = [{"type": "courseware"},
|
||||
{"type": "course_info", "name": "Course Info"},
|
||||
{"type": "discussion", "name": "Discussion"},
|
||||
{"type": "wiki", "name": "Wiki"},
|
||||
{"type": "progress", "name": "Progress"}]
|
||||
|
||||
modulestore('direct').update_metadata(new_course.location.url(), new_course.own_metadata)
|
||||
|
||||
create_all_course_groups(request.user, new_course.location)
|
||||
|
||||
@@ -15,7 +15,7 @@ class CMS.Views.TabsEdit extends Backbone.View
|
||||
|
||||
@$('.components').sortable(
|
||||
handle: '.drag-handle'
|
||||
update: (event, ui) => alert 'got it!'
|
||||
update: (event, ui) => alert 'not yet implemented!'
|
||||
helper: 'clone'
|
||||
opacity: '0.5'
|
||||
placeholder: 'component-placeholder'
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
<%block name="content">
|
||||
<div class="main-wrapper">
|
||||
<div class="inner-wrapper">
|
||||
<h1>Static Tabs</h1>
|
||||
<div>
|
||||
<h1>Static Tabs</h1>
|
||||
</div>
|
||||
<div class="main-column">
|
||||
<article class="unit-body window">
|
||||
<div class="tab-list">
|
||||
|
||||
@@ -266,6 +266,33 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
"""
|
||||
return self.metadata.get('tabs')
|
||||
|
||||
@tabs.setter
|
||||
def tabs(self, value):
|
||||
self.metadata['tabs'] = value
|
||||
|
||||
def add_tab_reference(self, tab_module):
|
||||
'''
|
||||
Since in CMS we can add static tabs via data, the current data model expects that
|
||||
the list of tabs be encapsulated in the course.
|
||||
VS[compat] we can rework this to avoid pointers to static tab modules once we fully deprecate filesystem support
|
||||
'''
|
||||
existing_tabs = self.tabs or []
|
||||
existing_tabs.append({'type':'static_tab', 'name' : tab_module.metadata.get('display_name'), 'url_slug' : tab_module.location.name})
|
||||
self.tabs = existing_tabs
|
||||
|
||||
|
||||
def update_tab_reference(self, tab_module):
|
||||
'''
|
||||
Since in CMS we can add static tabs via data, the current data model expects that
|
||||
the list of tabs be encapsulated in the course.
|
||||
VS[compat] we can rework this to avoid pointers to static tab modules once we fully deprecate filesystem support
|
||||
'''
|
||||
existing_tabs = self.tabs
|
||||
for tab in existing_tabs:
|
||||
if tab.get('url_slug') == tab_module.location.name:
|
||||
tab['name'] = tab_module.metadata.get('display_name')
|
||||
self.tabs = existing_tabs
|
||||
|
||||
@property
|
||||
def show_calculator(self):
|
||||
return self.metadata.get("show_calculator", None) == "Yes"
|
||||
|
||||
Reference in New Issue
Block a user