Studio support for cohorted courseware
TNL-652
This commit is contained in:
@@ -144,8 +144,3 @@ from django.utils.translation import ugettext as _
|
||||
</div>
|
||||
</div>
|
||||
</%block>
|
||||
|
||||
<!-- NOTE: remove this HTML if you want to not see the fake visibility modal -->
|
||||
<%block name="modal_placeholder">
|
||||
<%include file="ux/reference/modal_access-component.html" />
|
||||
</%block>
|
||||
|
||||
@@ -47,17 +47,9 @@
|
||||
<div class="wrapper-content wrapper">
|
||||
<section class="content">
|
||||
<article class="content-primary" role="main">
|
||||
% if configurations is None:
|
||||
<div class="notice notice-incontext notice-moduledisabled">
|
||||
<p class="copy">
|
||||
${_("This module is disabled at the moment.")}
|
||||
</p>
|
||||
</div>
|
||||
% else:
|
||||
<div class="ui-loading">
|
||||
<p><span class="spin"><i class="icon fa fa-refresh"></i></span> <span class="copy">${_("Loading")}</span></p>
|
||||
</div>
|
||||
% endif
|
||||
</article>
|
||||
<aside class="content-supplementary" role="complementary">
|
||||
<div class="bit">
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
<li class="action-item action-edit">
|
||||
<a href="#" class="edit-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-visibility">
|
||||
<a href="#" class="visibility-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-duplicate">
|
||||
<a href="#" class="duplicate-button action-button"></a>
|
||||
</li>
|
||||
@@ -71,6 +74,9 @@
|
||||
<li class="action-item action-edit">
|
||||
<a href="#" class="edit-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-visibility">
|
||||
<a href="#" class="visibility-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-duplicate">
|
||||
<a href="#" class="duplicate-button action-button"></a>
|
||||
</li>
|
||||
@@ -96,6 +102,9 @@
|
||||
<li class="action-item action-edit">
|
||||
<a href="#" class="edit-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-visibility">
|
||||
<a href="#" class="visibility-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-duplicate">
|
||||
<a href="#" class="duplicate-button action-button"></a>
|
||||
</li>
|
||||
@@ -151,6 +160,9 @@
|
||||
<li class="action-item action-edit">
|
||||
<a href="#" class="edit-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-visibility">
|
||||
<a href="#" class="visibility-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-duplicate">
|
||||
<a href="#" class="duplicate-button action-button"></a>
|
||||
</li>
|
||||
@@ -176,6 +188,9 @@
|
||||
<li class="action-item action-edit">
|
||||
<a href="#" class="edit-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-visibility">
|
||||
<a href="#" class="visibility-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-duplicate">
|
||||
<a href="#" class="duplicate-button action-button"></a>
|
||||
</li>
|
||||
@@ -201,6 +216,9 @@
|
||||
<li class="action-item action-edit">
|
||||
<a href="#" class="edit-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-visibility">
|
||||
<a href="#" class="visibility-button action-button"></a>
|
||||
</li>
|
||||
<li class="action-item action-duplicate">
|
||||
<a href="#" class="duplicate-button action-button"></a>
|
||||
</li>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<div class="xblock xblock-visibility_view" data-runtime-version="1" data-usage-id="i4x:;_;_edX;_mock"
|
||||
data-init="MockXBlock" data-runtime-class="StudioRuntime" tabindex="0">
|
||||
</div>
|
||||
@@ -77,13 +77,12 @@ var visibleToStaffOnly = visibilityState === 'staff_only';
|
||||
<% } else { %>
|
||||
<p class="visbility-copy copy"><%= gettext("Staff and Students") %></p>
|
||||
<% } %>
|
||||
|
||||
<!-- NOTE: @andyarmstrong, here's the new copy we're adding to the visibility summary UI to make sure we're as accurate as we can be at the final state of the unit/container's visibility -->
|
||||
<p class="note-visibility">
|
||||
<i class="icon icon-eye-open"></i>
|
||||
<span class="note-copy"><%= gettext("Some content in this unit is only visible to particular groups") %></span>
|
||||
</p>
|
||||
|
||||
<% if (hasContentGroupComponents) { %>
|
||||
<p class="note-visibility">
|
||||
<i class="icon icon-eye-open"></i>
|
||||
<span class="note-copy"><%= gettext("Some content in this unit is only visible to particular groups") %></span>
|
||||
</p>
|
||||
<% } %>
|
||||
<ul class="actions-inline">
|
||||
<li class="action-inline">
|
||||
<a href="" class="action-staff-lock" role="button" aria-pressed="<%= hasExplicitStaffLock %>">
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from contentstore import utils
|
||||
from contentstore.views.course import should_show_group_configurations_page
|
||||
import urllib
|
||||
%>
|
||||
|
||||
@@ -333,9 +332,7 @@ CMS.URL.UPLOAD_ASSET = '${upload_asset_url}';
|
||||
<ul>
|
||||
<li class="nav-item"><a href="${grading_config_url}">${_("Grading")}</a></li>
|
||||
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
|
||||
% if should_show_group_configurations_page(context_course):
|
||||
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
|
||||
% endif
|
||||
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
|
||||
<li class="nav-item"><a href="${advanced_config_url}">${_("Advanced Settings")}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from contentstore import utils
|
||||
from contentstore.views.course import should_show_group_configurations_page
|
||||
from django.utils.html import escapejs
|
||||
%>
|
||||
<%block name="title">${_("Advanced Settings")}</%block>
|
||||
@@ -92,9 +91,7 @@
|
||||
<li class="nav-item"><a href="${details_url}">${_("Details & Schedule")}</a></li>
|
||||
<li class="nav-item"><a href="${grading_url}">${_("Grading")}</a></li>
|
||||
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
|
||||
% if should_show_group_configurations_page(context_course):
|
||||
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
|
||||
% endif
|
||||
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
% endif
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%!
|
||||
from contentstore import utils
|
||||
from contentstore.views.course import should_show_group_configurations_page
|
||||
from django.utils.translation import ugettext as _
|
||||
%>
|
||||
|
||||
@@ -135,9 +134,7 @@
|
||||
<ul>
|
||||
<li class="nav-item"><a href="${detailed_settings_url}">${_("Details & Schedule")}</a></li>
|
||||
<li class="nav-item"><a href="${course_team_url}">${_("Course Team")}</a></li>
|
||||
% if should_show_group_configurations_page(context_course):
|
||||
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
|
||||
% endif
|
||||
<li class="nav-item"><a href="${utils.reverse_course_url('group_configurations_list_handler', context_course.id)}">${_("Group Configurations")}</a></li>
|
||||
<li class="nav-item"><a href="${advanced_settings_url}">${_("Advanced Settings")}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from contentstore.views.helpers import xblock_studio_url
|
||||
from contentstore.utils import is_visible_to_specific_content_groups
|
||||
import json
|
||||
%>
|
||||
<%
|
||||
@@ -38,8 +39,11 @@ messages = json.dumps(xblock.validate().to_json())
|
||||
<div class="studio-xblock-wrapper" data-locator="${xblock.location | h}" data-course-key="${xblock.location.course_key | h}">
|
||||
% endif
|
||||
|
||||
<!-- NOTE: @andyarmstrong, in order to style the case when an access level is set, we need to add a class to each xblock's wrapper. How does .has-visiblity-set sound? -->
|
||||
<section class="wrapper-xblock ${section_class} ${collapsible_class} has-visibility-set">
|
||||
<section class="wrapper-xblock ${section_class} ${collapsible_class}
|
||||
% if is_visible_to_specific_content_groups(xblock):
|
||||
has-group-visibility-set
|
||||
% endif
|
||||
">
|
||||
% endif
|
||||
|
||||
<header class="xblock-header xblock-header-${xblock.category}">
|
||||
@@ -77,7 +81,6 @@ messages = json.dumps(xblock.validate().to_json())
|
||||
<span class="sr">${_("Delete")}</span>
|
||||
</a>
|
||||
</li>
|
||||
<!-- NOTE: @andyarmstrong, here's a static version of the new access control we're adding. Remember we wanted to update the tooltip if particular groups were set on a component -->
|
||||
<li class="action-item action-visibility">
|
||||
<a href="#" data-tooltip="${_("Visibility Settings")}" class="visibility-button action-button">
|
||||
<i class="icon-eye-open"></i>
|
||||
|
||||
94
cms/templates/visibility_editor.html
Normal file
94
cms/templates/visibility_editor.html
Normal file
@@ -0,0 +1,94 @@
|
||||
<%
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_user_partition
|
||||
from contentstore.utils import ancestor_has_staff_lock
|
||||
|
||||
cohorted_user_partition = get_cohorted_user_partition(xblock.location.course_key)
|
||||
unsorted_groups = cohorted_user_partition.groups if cohorted_user_partition else []
|
||||
groups = sorted(unsorted_groups, key=lambda group: group.name)
|
||||
selected_group_ids = xblock.group_access.get(cohorted_user_partition.id, []) if cohorted_user_partition else []
|
||||
has_selected_groups = len(selected_group_ids) > 0
|
||||
is_staff_locked = ancestor_has_staff_lock(xblock)
|
||||
%>
|
||||
|
||||
<div class="modal-section visibility-summary">
|
||||
% if len(groups) == 0:
|
||||
<div class="is-not-configured has-actions">
|
||||
<h4 class="title">${_('You have not set up any groups to manage visibility with.')}</h4>
|
||||
|
||||
<div class="copy">
|
||||
<p>${_('Groups are a way for you to organize content in your course with a particular student experience in mind. They are commonly used to facilitate content and pedagogical experiments as well as provide different tracks of content.')}</p>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<a href="${manage_groups_url}" class="action action-primary action-settings">${_('Manage groups in this course')}</a>
|
||||
</div>
|
||||
</div>
|
||||
% elif is_staff_locked:
|
||||
<div class="summary-message summary-message-warning visibility-summary-message">
|
||||
<i class="icon icon-warning-sign"></i>
|
||||
<p class="copy">${_('The Unit this component is contained in is hidden from students. Visibility settings here will be trumped by this.')}</p>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
|
||||
% if len(groups) > 0:
|
||||
<form class="visibility-controls-form" method="post" action="">
|
||||
|
||||
<div class="modal-section visibility-controls">
|
||||
<h3 class="modal-section-title">${_('Set visibility to:')}</h3>
|
||||
|
||||
<div class="modal-section-content">
|
||||
|
||||
<section class="visibility-controls-primary">
|
||||
<ul class="list-fields list-radio">
|
||||
<li class="field field-radio field-visibility-level">
|
||||
<input type="radio" id="visibility-level-all" name="visibility-level" value="" class="input input-radio visibility-level-all" ${'checked="checked"' if not has_selected_groups else ''} />
|
||||
<label for="visibility-level-all" class="label">${_('All Students and Staff')}</label>
|
||||
</li>
|
||||
|
||||
<li class="field field-radio field-visibility-level">
|
||||
<input type="radio" id="visibility-level-specific" name="visibility-level" value="" class="input input-radio visibility-level-specific" ${'checked="checked"' if has_selected_groups else ''} />
|
||||
<label for="visibility-level-specific" class="label">${_('Specific Content Groups')}</label>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<div class="wrapper-visibility-specific" data-user-partition-id="${cohorted_user_partition.id}">
|
||||
<section class="visibility-controls-secondary">
|
||||
<div class="visibility-controls-group">
|
||||
<h4 class="visibility-controls-title modal-subsection-title sr">${_('Content Groups')}</h4>
|
||||
<ul class="list-fields list-checkbox">
|
||||
<%
|
||||
missing_group_ids = set(selected_group_ids)
|
||||
%>
|
||||
% for group in groups:
|
||||
<%
|
||||
is_group_selected = group.id in selected_group_ids
|
||||
if is_group_selected:
|
||||
missing_group_ids.remove(group.id)
|
||||
%>
|
||||
<li class="field field-checkbox field-visibility-content-group">
|
||||
<input type="checkbox" id="visibility-content-group-${group.id}" name="visibility-content-group" value="${group.id}" class="input input-checkbox" ${'checked="checked"' if group.id in selected_group_ids else ''}/>
|
||||
<label for="visibility-content-group-${group.id}" class="label">${group.name | h}</label>
|
||||
</li>
|
||||
% endfor
|
||||
|
||||
% for group_id in missing_group_ids:
|
||||
<li class="field field-checkbox field-visibility-content-group was-removed">
|
||||
<input type="checkbox" id="visibility-content-group-${group_id}" name="visibility-content-group" value="${group_id}" class="input input-checkbox" checked="checked" />
|
||||
<label for="visibility-content-group-${group_id}" class="label">
|
||||
${_('Deleted Content Group')}
|
||||
<span class="note">${_('Content group no longer exists. Please choose another or allow access to All Students and staff')}</span>
|
||||
</label>
|
||||
</li>
|
||||
% endfor
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
% endif
|
||||
@@ -3,7 +3,6 @@
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from contentstore.context_processors import doc_url
|
||||
from contentstore.views.course import should_show_group_configurations_page
|
||||
%>
|
||||
<%page args="online_help_token"/>
|
||||
|
||||
@@ -93,11 +92,9 @@
|
||||
<li class="nav-item nav-course-settings-team">
|
||||
<a href="${course_team_url}">${_("Course Team")}</a>
|
||||
</li>
|
||||
% if should_show_group_configurations_page(context_course):
|
||||
<li class="nav-item nav-course-settings-group-configurations">
|
||||
<a href="${reverse('contentstore.views.group_configurations_list_handler', kwargs={'course_key_string': unicode(course_key)})}">${_("Group Configurations")}</a>
|
||||
</li>
|
||||
% endif
|
||||
<li class="nav-item nav-course-settings-group-configurations">
|
||||
<a href="${reverse('contentstore.views.group_configurations_list_handler', kwargs={'course_key_string': unicode(course_key)})}">${_("Group Configurations")}</a>
|
||||
</li>
|
||||
<li class="nav-item nav-course-settings-advanced">
|
||||
<a href="${advanced_settings_url}">${_("Advanced Settings")}</a>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user