diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index a5a3b47bce..ea3e3ecd6a 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -9,6 +9,8 @@ DIRECT_ONLY_CATEGORIES = ['course', 'chapter', 'sequential', 'about', 'static_ta #In order to instantiate an open ended tab automatically, need to have this data OPEN_ENDED_PANEL = {"name": "Open Ended Panel", "type": "open_ended"} +NOTES_PANEL = {"name": "My Notes", "type": "notes"} +EXTRA_TAB_PANELS = dict([(p['type'], p) for p in [OPEN_ENDED_PANEL, NOTES_PANEL]]) def get_modulestore(location): @@ -192,9 +194,10 @@ class CoursePageNames: Checklists = "checklists" -def add_open_ended_panel_tab(course): +def add_extra_panel_tab(tab_type, course): """ - Used to add the open ended panel tab to a course if it does not exist. + Used to add the panel tab to a course if it does not exist. + @param tab_type: A string representing the tab type. @param course: A course object from the modulestore. @return: Boolean indicating whether or not a tab was added and a list of tabs for the course. """ @@ -202,16 +205,19 @@ def add_open_ended_panel_tab(course): course_tabs = copy.copy(course.tabs) changed = False #Check to see if open ended panel is defined in the course - if OPEN_ENDED_PANEL not in course_tabs: + + tab_panel = EXTRA_TAB_PANELS.get(tab_type) + if tab_panel not in course_tabs: #Add panel to the tabs if it is not defined - course_tabs.append(OPEN_ENDED_PANEL) + course_tabs.append(tab_panel) changed = True return changed, course_tabs -def remove_open_ended_panel_tab(course): +def remove_extra_panel_tab(tab_type, course): """ - Used to remove the open ended panel tab from a course if it exists. + Used to remove the panel tab from a course if it exists. + @param tab_type: A string representing the tab type. @param course: A course object from the modulestore. @return: Boolean indicating whether or not a tab was added and a list of tabs for the course. """ @@ -219,8 +225,10 @@ def remove_open_ended_panel_tab(course): course_tabs = copy.copy(course.tabs) changed = False #Check to see if open ended panel is defined in the course - if OPEN_ENDED_PANEL in course_tabs: + + tab_panel = EXTRA_TAB_PANELS.get(tab_type) + if tab_panel in course_tabs: #Add panel to the tabs if it is not defined - course_tabs = [ct for ct in course_tabs if ct != OPEN_ENDED_PANEL] + course_tabs = [ct for ct in course_tabs if ct != tab_panel] changed = True return changed, course_tabs diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py index caf3901e03..8d0878809e 100644 --- a/cms/djangoapps/contentstore/views.py +++ b/cms/djangoapps/contentstore/views.py @@ -49,8 +49,8 @@ from auth.authz import is_user_in_course_group_role, get_users_in_course_group_b 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, \ - UnitState, get_course_for_item, get_url_reverse, add_open_ended_panel_tab, \ - remove_open_ended_panel_tab + UnitState, get_course_for_item, get_url_reverse, add_extra_panel_tab, \ + remove_extra_panel_tab from xmodule.modulestore.xml_importer import import_from_xml from contentstore.course_info_model import get_course_updates, \ @@ -72,7 +72,8 @@ log = logging.getLogger(__name__) COMPONENT_TYPES = ['customtag', 'discussion', 'html', 'problem', 'video'] OPEN_ENDED_COMPONENT_TYPES = ["combinedopenended", "peergrading"] -ADVANCED_COMPONENT_TYPES = ['annotatable'] + OPEN_ENDED_COMPONENT_TYPES +NOTE_COMPONENT_TYPES = ['notes'] +ADVANCED_COMPONENT_TYPES = ['annotatable'] + OPEN_ENDED_COMPONENT_TYPES + NOTE_COMPONENT_TYPES ADVANCED_COMPONENT_CATEGORY = 'advanced' ADVANCED_COMPONENT_POLICY_KEY = 'advanced_modules' @@ -1274,32 +1275,43 @@ def course_advanced_updates(request, org, course, name): #Check to see if the user instantiated any advanced components. This is a hack to add the open ended panel tab #to a course automatically if the user has indicated that they want to edit the combinedopenended or peergrading #module, and to remove it if they have removed the open ended elements. + #Note: it has also been extended to include additional component types beyond openended. if ADVANCED_COMPONENT_POLICY_KEY in request_body: #Check to see if the user instantiated any open ended components - found_oe_type = False #Get the course so that we can scrape current tabs course_module = modulestore().get_item(location) - for oe_type in OPEN_ENDED_COMPONENT_TYPES: - if oe_type in request_body[ADVANCED_COMPONENT_POLICY_KEY]: - #Add an open ended tab to the course if needed - changed, new_tabs = add_open_ended_panel_tab(course_module) - #If a tab has been added to the course, then send the metadata along to CourseMetadata.update_from_json + tab_component_types = ['open_ended', 'notes'] + tab_component_map = { + 'open_ended': OPEN_ENDED_COMPONENT_TYPES, + 'notes': NOTE_COMPONENT_TYPES, + } + + for tab_type in tab_component_types: + component_types = tab_component_map.get(tab_type) + found_ac_type = False + for ac_type in component_types: + if ac_type in request_body[ADVANCED_COMPONENT_POLICY_KEY]: + #Add an open ended tab to the course if needed + changed, new_tabs = add_extra_panel_tab(tab_type, course_module) + #If a tab has been added to the course, then send the metadata along to CourseMetadata.update_from_json + if changed: + course_module.tabs = new_tabs + request_body.update({'tabs': new_tabs}) + #Indicate that tabs should not be filtered out of the metadata + filter_tabs = False + #Set this flag to avoid the open ended tab removal code below. + found_ac_type = True + break + #If we did not find an open ended module type in the advanced settings, + # we may need to remove the open ended tab from the course. + if not found_ac_type: + #Remove open ended tab to the course if needed + changed, new_tabs = remove_extra_panel_tab(tab_type, course_module) if changed: + course_module.tabs = new_tabs request_body.update({'tabs': new_tabs}) #Indicate that tabs should not be filtered out of the metadata filter_tabs = False - #Set this flag to avoid the open ended tab removal code below. - found_oe_type = True - break - #If we did not find an open ended module type in the advanced settings, - # we may need to remove the open ended tab from the course. - if not found_oe_type: - #Remove open ended tab to the course if needed - changed, new_tabs = remove_open_ended_panel_tab(course_module) - if changed: - request_body.update({'tabs': new_tabs}) - #Indicate that tabs should not be filtered out of the metadata - filter_tabs = False response_json = json.dumps(CourseMetadata.update_from_json(location, request_body, filter_tabs=filter_tabs)) return HttpResponse(response_json, mimetype="application/json")