Ability to hide Pages from students
This commit is contained in:
@@ -546,9 +546,16 @@ def _save_xblock(user, xblock, data=None, children_strings=None, metadata=None,
|
||||
# find the course's reference to this tab and update the name.
|
||||
static_tab = CourseTabList.get_tab_by_slug(course.tabs, xblock.location.name)
|
||||
# only update if changed
|
||||
if static_tab and static_tab['name'] != xblock.display_name:
|
||||
static_tab['name'] = xblock.display_name
|
||||
store.update_item(course, user.id)
|
||||
if static_tab:
|
||||
update_tab = False
|
||||
if static_tab['name'] != xblock.display_name:
|
||||
static_tab['name'] = xblock.display_name
|
||||
update_tab = True
|
||||
if static_tab['course_staff_only'] != xblock.course_staff_only:
|
||||
static_tab['course_staff_only'] = xblock.course_staff_only
|
||||
update_tab = True
|
||||
if update_tab:
|
||||
store.update_item(course, user.id)
|
||||
|
||||
result = {
|
||||
'id': unicode(xblock.location),
|
||||
|
||||
@@ -368,6 +368,13 @@ class StaticTabFields(object):
|
||||
scope=Scope.settings,
|
||||
default="Empty",
|
||||
)
|
||||
course_staff_only = Boolean(
|
||||
display_name=_("Hide Page From Learners"),
|
||||
help=_("If you select this option, only course team members with"
|
||||
" the Staff or Admin role see this page."),
|
||||
default=False,
|
||||
scope=Scope.settings
|
||||
)
|
||||
data = String(
|
||||
default=textwrap.dedent(u"""\
|
||||
<p>Add the content you want students to see on this page.</p>
|
||||
|
||||
@@ -730,6 +730,7 @@ class XMLModuleStore(ModuleStoreReadBase):
|
||||
tab = CourseTabList.get_tab_by_slug(tab_list=course_descriptor.tabs, url_slug=slug)
|
||||
if tab:
|
||||
module.display_name = tab.name
|
||||
module.course_staff_only = tab.course_staff_only
|
||||
module.data_dir = course_dir
|
||||
module.save()
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@ class CourseTab(object):
|
||||
# If there is a single view associated with this tab, this is the name of it
|
||||
view_name = None
|
||||
|
||||
# True if this tab should be displayed only for instructors
|
||||
course_staff_only = False
|
||||
|
||||
def __init__(self, tab_dict):
|
||||
"""
|
||||
Initializes class members with values passed in by subclasses.
|
||||
@@ -69,6 +72,7 @@ class CourseTab(object):
|
||||
self.name = tab_dict.get('name', self.title)
|
||||
self.tab_id = tab_dict.get('tab_id', getattr(self, 'tab_id', self.type))
|
||||
self.link_func = tab_dict.get('link_func', link_reverse_func(self.view_name))
|
||||
self.course_staff_only = tab_dict.get('course_staff_only', False)
|
||||
|
||||
self.is_hidden = tab_dict.get('is_hidden', False)
|
||||
|
||||
@@ -105,6 +109,8 @@ class CourseTab(object):
|
||||
return self.tab_id
|
||||
elif key == 'is_hidden':
|
||||
return self.is_hidden
|
||||
elif key == 'course_staff_only':
|
||||
return self.course_staff_only
|
||||
else:
|
||||
raise KeyError('Key {0} not present in tab {1}'.format(key, self.to_json()))
|
||||
|
||||
@@ -121,6 +127,8 @@ class CourseTab(object):
|
||||
self.tab_id = value
|
||||
elif key == 'is_hidden':
|
||||
self.is_hidden = value
|
||||
elif key == 'course_staff_only':
|
||||
self.course_staff_only = value
|
||||
else:
|
||||
raise KeyError('Key {0} cannot be set in tab {1}'.format(key, self.to_json()))
|
||||
|
||||
@@ -179,7 +187,7 @@ class CourseTab(object):
|
||||
Returns:
|
||||
a dictionary with keys for the properties of the CourseTab object.
|
||||
"""
|
||||
to_json_val = {'type': self.type, 'name': self.name}
|
||||
to_json_val = {'type': self.type, 'name': self.name, 'course_staff_only': self.course_staff_only}
|
||||
if self.is_hidden:
|
||||
to_json_val.update({'is_hidden': True})
|
||||
return to_json_val
|
||||
|
||||
@@ -476,6 +476,21 @@ class ImportTestCase(BaseCourseTestCase):
|
||||
# appropriate attribute maps -- 'graded' should be True, not 'true'
|
||||
self.assertEqual(toy.graded, True)
|
||||
|
||||
def test_static_tabs_import(self):
|
||||
"""Make sure that the static tabs are imported correctly"""
|
||||
|
||||
modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy'])
|
||||
|
||||
location_tab_syllabus = Location("edX", "toy", "2012_Fall", "static_tab", "syllabus", None)
|
||||
toy_tab_syllabus = modulestore.get_item(location_tab_syllabus)
|
||||
self.assertEqual(toy_tab_syllabus.display_name, 'Syllabus')
|
||||
self.assertEqual(toy_tab_syllabus.course_staff_only, False)
|
||||
|
||||
location_tab_resources = Location("edX", "toy", "2012_Fall", "static_tab", "resources", None)
|
||||
toy_tab_resources = modulestore.get_item(location_tab_resources)
|
||||
self.assertEqual(toy_tab_resources.display_name, 'Resources')
|
||||
self.assertEqual(toy_tab_resources.course_staff_only, True)
|
||||
|
||||
def test_definition_loading(self):
|
||||
"""When two courses share the same org and course name and
|
||||
both have a module with the same url_name, the definitions shouldn't clash.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{"type": "courseware"},
|
||||
{"type": "course_info", "name": "Course Info"},
|
||||
{"type": "static_tab", "url_slug": "syllabus", "name": "Syllabus"},
|
||||
{"type": "static_tab", "url_slug": "resources", "name": "Resources"},
|
||||
{"type": "static_tab", "url_slug": "resources", "name": "Resources", "course_staff_only": true},
|
||||
{"type": "discussion", "name": "Discussion"},
|
||||
{"type": "wiki", "name": "Wiki"},
|
||||
{"type": "progress", "name": "Progress"}
|
||||
|
||||
@@ -9,6 +9,7 @@ from courseware.access import has_access
|
||||
from courseware.entrance_exams import user_must_complete_entrance_exam
|
||||
from openedx.core.lib.course_tabs import CourseTabPluginManager
|
||||
from student.models import CourseEnrollment
|
||||
from student.roles import CourseStaffRole
|
||||
from xmodule.tabs import CourseTab, CourseTabList, key_checker
|
||||
|
||||
|
||||
@@ -299,9 +300,12 @@ def get_course_tab_list(request, course):
|
||||
if must_complete_ee:
|
||||
# Hide all of the tabs except for 'Courseware'
|
||||
# Rename 'Courseware' tab to 'Entrance Exam'
|
||||
if tab.type is not 'courseware':
|
||||
if tab.type != 'courseware':
|
||||
continue
|
||||
tab.name = _("Entrance Exam")
|
||||
if tab.type == 'static_tab' and tab.course_staff_only and \
|
||||
not bool(user and CourseStaffRole(course.id).has_user(user)):
|
||||
continue
|
||||
course_tab_list.append(tab)
|
||||
|
||||
# Add in any dynamic tabs, i.e. those that are not persisted
|
||||
|
||||
@@ -686,6 +686,35 @@ class CourseTabListTestCase(TabListTestCase):
|
||||
# get tab by id
|
||||
self.assertEquals(xmodule_tabs.CourseTabList.get_tab_by_id(self.course.tabs, tab.tab_id), tab)
|
||||
|
||||
def test_course_tabs_staff_only(self):
|
||||
"""
|
||||
Tests the static tabs that available only for instructor
|
||||
"""
|
||||
self.course.tabs.append(xmodule_tabs.CourseTab.load('static_tab', name='Static Tab Free',
|
||||
url_slug='extra_tab_1',
|
||||
course_staff_only=False))
|
||||
self.course.tabs.append(xmodule_tabs.CourseTab.load('static_tab', name='Static Tab Instructors Only',
|
||||
url_slug='extra_tab_2',
|
||||
course_staff_only=True))
|
||||
self.course.save()
|
||||
|
||||
user = self.create_mock_user(is_authenticated=True, is_staff=False, is_enrolled=True)
|
||||
request = get_request_for_user(user)
|
||||
course_tab_list = get_course_tab_list(request, self.course)
|
||||
name_list = [x.name for x in course_tab_list]
|
||||
self.assertIn('Static Tab Free', name_list)
|
||||
self.assertNotIn('Static Tab Instructors Only', name_list)
|
||||
|
||||
# Login as member of staff
|
||||
self.client.logout()
|
||||
staff_user = StaffFactory(course_key=self.course.id)
|
||||
self.client.login(username=staff_user.username, password='test')
|
||||
request = get_request_for_user(staff_user)
|
||||
course_tab_list_staff = get_course_tab_list(request, self.course)
|
||||
name_list_staff = [x.name for x in course_tab_list_staff]
|
||||
self.assertIn('Static Tab Free', name_list_staff)
|
||||
self.assertIn('Static Tab Instructors Only', name_list_staff)
|
||||
|
||||
|
||||
@attr(shard=1)
|
||||
class ProgressTestCase(TabTestCase):
|
||||
|
||||
Reference in New Issue
Block a user