feat: Studio menu/button to display Unit's Tags (feature flagged) (#33563)
This commit is contained in:
@@ -45,7 +45,12 @@ from xmodule.video_block import VideoBlock
|
||||
|
||||
from cms.djangoapps.contentstore.config import waffle
|
||||
from cms.djangoapps.contentstore.tests.utils import AjaxEnabledTestClient, CourseTestCase, get_url, parse_json
|
||||
from cms.djangoapps.contentstore.utils import delete_course, reverse_course_url, reverse_url
|
||||
from cms.djangoapps.contentstore.utils import (
|
||||
delete_course,
|
||||
reverse_course_url,
|
||||
reverse_url,
|
||||
get_taxonomy_tags_widget_url,
|
||||
)
|
||||
from cms.djangoapps.contentstore.views.component import ADVANCED_COMPONENT_TYPES
|
||||
from common.djangoapps.course_action_state.managers import CourseActionStateItemNotFoundError
|
||||
from common.djangoapps.course_action_state.models import CourseRerunState, CourseRerunUIStateManager
|
||||
@@ -1410,12 +1415,16 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
'assets_handler',
|
||||
course.location.course_key
|
||||
)
|
||||
|
||||
taxonomy_tags_widget_url = get_taxonomy_tags_widget_url(course.id)
|
||||
|
||||
self.assertContains(
|
||||
resp,
|
||||
'<article class="outline outline-complex outline-course" data-locator="{locator}" data-course-key="{course_key}" data-course-assets="{assets_url}">'.format( # lint-amnesty, pylint: disable=line-too-long
|
||||
'<article class="outline outline-complex outline-course" data-locator="{locator}" data-course-key="{course_key}" data-course-assets="{assets_url}" data-taxonomy-tags-widget-url="{taxonomy_tags_widget_url}" >'.format( # lint-amnesty, pylint: disable=line-too-long
|
||||
locator=str(course.location),
|
||||
course_key=str(course.id),
|
||||
assets_url=assets_url,
|
||||
taxonomy_tags_widget_url=taxonomy_tags_widget_url,
|
||||
),
|
||||
status_code=200,
|
||||
html=True
|
||||
|
||||
@@ -446,6 +446,21 @@ def get_taxonomy_list_url():
|
||||
return taxonomy_list_url
|
||||
|
||||
|
||||
def get_taxonomy_tags_widget_url(course_locator) -> str:
|
||||
"""
|
||||
Gets course authoring microfrontend URL for taxonomy tags drawer widget view.
|
||||
|
||||
The `content_id` needs to be appended to the end of the URL when using it.
|
||||
"""
|
||||
taxonomy_tags_widget_url = None
|
||||
# Uses the same waffle flag as taxonomy list page
|
||||
if use_tagging_taxonomy_list_page():
|
||||
mfe_base_url = get_course_authoring_url(course_locator)
|
||||
if mfe_base_url:
|
||||
taxonomy_tags_widget_url = f'{mfe_base_url}/tagging/components/widget/'
|
||||
return taxonomy_tags_widget_url
|
||||
|
||||
|
||||
def course_import_olx_validation_is_enabled():
|
||||
"""
|
||||
Check if course olx validation is enabled on course import.
|
||||
|
||||
@@ -105,6 +105,7 @@ from ..utils import (
|
||||
get_lms_link_for_item,
|
||||
get_proctored_exam_settings_url,
|
||||
get_course_outline_url,
|
||||
get_taxonomy_tags_widget_url,
|
||||
get_studio_home_url,
|
||||
get_updates_url,
|
||||
get_advanced_settings_url,
|
||||
@@ -688,6 +689,7 @@ def course_index(request, course_key):
|
||||
'mfe_proctored_exam_settings_url': get_proctored_exam_settings_url(course_block.id),
|
||||
'advance_settings_url': reverse_course_url('advanced_settings_handler', course_block.id),
|
||||
'proctoring_errors': proctoring_errors,
|
||||
'taxonomy_tags_widget_url': get_taxonomy_tags_widget_url(course_block.id),
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ from xblock.core import XBlock
|
||||
from xblock.fields import Scope
|
||||
|
||||
from cms.djangoapps.contentstore.config.waffle import SHOW_REVIEW_RULES_FLAG
|
||||
from cms.djangoapps.contentstore.toggles import ENABLE_COPY_PASTE_UNITS
|
||||
from cms.djangoapps.contentstore.toggles import ENABLE_COPY_PASTE_UNITS, use_tagging_taxonomy_list_page
|
||||
from cms.djangoapps.models.settings.course_grading import CourseGradingModel
|
||||
from cms.lib.ai_aside_summary_config import AiAsideSummaryConfig
|
||||
from common.djangoapps.edxmako.services import MakoService
|
||||
@@ -1397,6 +1397,10 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
|
||||
# If the ENABLE_COPY_PASTE_UNITS feature flag is enabled, we show the newer menu that allows copying/pasting
|
||||
xblock_info["enable_copy_paste_units"] = ENABLE_COPY_PASTE_UNITS.is_enabled()
|
||||
|
||||
# If the ENABLE_TAGGING_TAXONOMY_LIST_PAGE feature flag is enabled, we show the "Manage Tags" options
|
||||
if use_tagging_taxonomy_list_page():
|
||||
xblock_info["use_tagging_taxonomy_list_page"] = True
|
||||
|
||||
xblock_info[
|
||||
"has_partition_group_components"
|
||||
] = has_children_visible_to_specific_partition_groups(xblock)
|
||||
|
||||
@@ -458,6 +458,43 @@ function(
|
||||
event.stopPropagation();
|
||||
},
|
||||
|
||||
closeManageTagsDrawer(drawer, drawerCover) {
|
||||
$(drawerCover).css('display', 'none');
|
||||
$(drawer).empty();
|
||||
$(drawer).css('display', 'none');
|
||||
$('body').removeClass('drawer-open');
|
||||
},
|
||||
|
||||
openManageTagsDrawer(event) {
|
||||
const drawer = document.querySelector("#manage-tags-drawer");
|
||||
const drawerCover = document.querySelector(".drawer-cover")
|
||||
const article = document.querySelector('[data-taxonomy-tags-widget-url]');
|
||||
const taxonomyTagsWidgetUrl = $(article).attr('data-taxonomy-tags-widget-url');
|
||||
const contentId = this.model.get('id');
|
||||
|
||||
// Add handler to close drawer when dark background is clicked
|
||||
$(drawerCover).click(function() {
|
||||
this.closeManageTagsDrawer(drawer, drawerCover);
|
||||
}.bind(this));
|
||||
|
||||
// Add event listen to close drawer when close button is clicked from within the Iframe
|
||||
window.addEventListener("message", function (event) {
|
||||
if (event.data === 'closeManageTagsDrawer') {
|
||||
this.closeManageTagsDrawer(drawer, drawerCover)
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
$(drawerCover).css('display', 'block');
|
||||
// xss-lint: disable=javascript-jquery-html
|
||||
$(drawer).html(
|
||||
`<iframe src="${taxonomyTagsWidgetUrl}${contentId}" onload="this.contentWindow.focus()" frameborder="0" style="width: 100%; height: 100%;"></iframe>`
|
||||
);
|
||||
$(drawer).css('display', 'block');
|
||||
|
||||
// Prevent background from being scrollable when drawer is open
|
||||
$('body').addClass('drawer-open');
|
||||
},
|
||||
|
||||
addButtonActions: function(element) {
|
||||
XBlockOutlineView.prototype.addButtonActions.apply(this, arguments);
|
||||
element.find('.configure-button').click(function(event) {
|
||||
@@ -478,6 +515,10 @@ function(
|
||||
event.preventDefault();
|
||||
this.copyXBlock();
|
||||
});
|
||||
element.find('.manage-tags-button').click((event) => {
|
||||
event.preventDefault();
|
||||
this.openManageTagsDrawer();
|
||||
});
|
||||
element.find('.paste-component-button').click((event) => {
|
||||
event.preventDefault();
|
||||
this.pasteUnit(event);
|
||||
|
||||
@@ -114,6 +114,7 @@ function($, _, gettext, BaseView, ViewUtils, XBlockViewUtils, XBlockStringFieldE
|
||||
staffOnlyMessage: this.model.get('staff_only_message'),
|
||||
course: course,
|
||||
enableCopyPasteUnits: this.model.get("enable_copy_paste_units"), // ENABLE_COPY_PASTE_UNITS waffle flag
|
||||
useTaggingTaxonomyListPage: this.model.get("use_tagging_taxonomy_list_page"), // ENABLE_TAGGING_TAXONOMY_LIST_PAGE waffle flag
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
@import 'elements/uploaded-assets'; // layout for asset tables
|
||||
@import 'elements/creative-commons';
|
||||
@import 'elements/tooltip';
|
||||
@import 'elements/drawer';
|
||||
|
||||
// +Base - Specific Views
|
||||
// ====================
|
||||
|
||||
30
cms/static/sass/elements/_drawer.scss
Normal file
30
cms/static/sass/elements/_drawer.scss
Normal file
@@ -0,0 +1,30 @@
|
||||
// studio - elements - side drawers
|
||||
// ====================
|
||||
|
||||
.drawer-cover {
|
||||
@extend %ui-depth3;
|
||||
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.drawer {
|
||||
@extend %ui-depth4;
|
||||
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 33.33vw;
|
||||
height: 100vh;
|
||||
background-color: $gray-l4;
|
||||
}
|
||||
|
||||
body.drawer-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -281,7 +281,7 @@ from django.urls import reverse
|
||||
assets_url = reverse('assets_handler', kwargs={'course_key_string': str(course_locator.course_key)})
|
||||
%>
|
||||
<h2 class="sr">${_("Course Outline")}</h2>
|
||||
<article class="outline outline-complex outline-course" data-locator="${course_locator}" data-course-key="${course_locator.course_key}" data-course-assets="${assets_url}">
|
||||
<article class="outline outline-complex outline-course" data-locator="${course_locator}" data-course-key="${course_locator.course_key}" data-course-assets="${assets_url}" data-taxonomy-tags-widget-url="${taxonomy_tags_widget_url}">
|
||||
</article>
|
||||
</div>
|
||||
<div class="ui-loading">
|
||||
@@ -321,4 +321,7 @@ from django.urls import reverse
|
||||
</aside>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div id="manage-tags-drawer" class="drawer"></div>
|
||||
<div class="drawer-cover"></div>
|
||||
</%block>
|
||||
|
||||
@@ -169,6 +169,17 @@ if (is_proctored_exam) {
|
||||
</a>
|
||||
</li>
|
||||
<% } %>
|
||||
|
||||
<% if (xblockInfo.isVertical() && typeof useTaggingTaxonomyListPage !== "undefined" && useTaggingTaxonomyListPage) { %>
|
||||
<li class="action-item">
|
||||
<a href="#" data-tooltip="<%- gettext('Manage Tags') %>" class="manage-tags-button action-button">
|
||||
<span class="icon fa fa-tag" aria-hidden="true"></span>
|
||||
<span>?</span>
|
||||
<span class="sr action-button-text"><%- gettext('Manage Tags') %></span>
|
||||
</a>
|
||||
</li>
|
||||
<% } %>
|
||||
|
||||
<% if (typeof enableCopyPasteUnits !== "undefined" && enableCopyPasteUnits) { %>
|
||||
<!--
|
||||
If the ENABLE_COPY_PASTE_UNITS feature flag is enabled, all these actions (besides "Publish")
|
||||
@@ -192,6 +203,11 @@ if (is_proctored_exam) {
|
||||
<li class="nav-item">
|
||||
<a class="copy-button" href="#" role="button"><%- gettext('Copy to Clipboard') %></a>
|
||||
</li>
|
||||
<% if (typeof useTaggingTaxonomyListPage !== "undefined" && useTaggingTaxonomyListPage) { %>
|
||||
<li class="nav-item">
|
||||
<a class="manage-tags-button" href="#" role="button"><%- gettext('Manage Tags') %></a>
|
||||
</li>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% if (xblockInfo.isDuplicable()) { %>
|
||||
<li class="nav-item">
|
||||
|
||||
Reference in New Issue
Block a user