feat: Tag count in components on Studio Unit page(#33928)

This commit is contained in:
Chris Chávez
2024-01-12 12:35:23 -05:00
committed by GitHub
parent 019888f3d1
commit 90879d167f
8 changed files with 75 additions and 7 deletions

View File

@@ -28,7 +28,7 @@ from openedx.core.lib.xblock_utils import (
from xmodule.modulestore.django import (
modulestore,
) # lint-amnesty, pylint: disable=wrong-import-order
from cms.djangoapps.contentstore.toggles import use_tagging_taxonomy_list_page
from xmodule.x_module import (
AUTHOR_VIEW,
@@ -51,7 +51,10 @@ from cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers import (
get_xblock,
delete_orphans,
)
from cms.djangoapps.contentstore.xblock_storage_handlers.xblock_helpers import usage_key_with_run
from cms.djangoapps.contentstore.xblock_storage_handlers.xblock_helpers import (
usage_key_with_run,
get_children_tags_count,
)
__all__ = [
@@ -230,6 +233,11 @@ def xblock_view_handler(request, usage_key_string, view_name):
force_render = request.GET.get("force_render", None)
# Fetch tags of children components
tags_count_map = {}
if use_tagging_taxonomy_list_page():
tags_count_map = get_children_tags_count(xblock)
# Set up the context to be passed to each XBlock's render method.
context = request.GET.dict()
context.update(
@@ -245,6 +253,7 @@ def xblock_view_handler(request, usage_key_string, view_name):
"paging": paging,
"force_render": force_render,
"item_url": "/container/{usage_key}",
"tags_count_map": tags_count_map,
}
)
fragment = get_preview_fragment(request, xblock, context)

View File

@@ -302,6 +302,10 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
can_edit = context.get('can_edit', True)
# Is this a course or a library?
is_course = xblock.scope_ids.usage_id.context_key.is_course
tags_count_map = context.get('tags_count_map')
tags_count = 0
if tags_count_map:
tags_count = tags_count_map.get(str(xblock.location), 0)
template_context = {
'xblock_context': context,
'xblock': xblock,
@@ -318,7 +322,8 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
'can_add': context.get('can_add', True),
'can_move': context.get('can_move', is_course),
'language': getattr(course, 'language', None),
'is_course': is_course
'is_course': is_course,
'tags_count': tags_count,
}
add_webpack_js_to_fragment(frag, "js/factories/xblock_validation")

View File

@@ -17,6 +17,7 @@ from openedx_events.content_authoring.data import DuplicatedXBlockData
from openedx_events.content_authoring.signals import XBLOCK_DUPLICATED
from openedx_events.tests.utils import OpenEdxEventsTestMixin
from edx_proctoring.exceptions import ProctoredExamNotFoundException
from edx_toggles.toggles.testutils import override_waffle_flag
from opaque_keys import InvalidKeyError
from opaque_keys.edx.asides import AsideUsageKeyV2
from opaque_keys.edx.keys import CourseKey, UsageKey
@@ -83,6 +84,7 @@ from cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers import (
add_container_page_publishing_info,
create_xblock_info,
)
from cms.djangoapps.contentstore.toggles import ENABLE_TAGGING_TAXONOMY_LIST_PAGE
class AsideTest(XBlockAside):
@@ -269,6 +271,37 @@ class GetItemTest(ItemTest):
),
)
@override_waffle_flag(ENABLE_TAGGING_TAXONOMY_LIST_PAGE, True)
@patch("cms.djangoapps.contentstore.xblock_storage_handlers.xblock_helpers.get_object_tag_counts")
def test_tag_count_in_container_fragment(self, mock_get_object_tag_counts):
root_usage_key = self._create_vertical()
# Add a problem beneath a child vertical
child_vertical_usage_key = self._create_vertical(
parent_usage_key=root_usage_key
)
resp = self.create_xblock(
parent_usage_key=child_vertical_usage_key,
category="problem",
boilerplate="multiplechoice.yaml",
)
self.assertEqual(resp.status_code, 200)
usage_key = self.response_usage_key(resp)
# Get the preview HTML without tags
mock_get_object_tag_counts.return_value = {}
html, __ = self._get_container_preview(root_usage_key)
self.assertIn("wrapper-xblock", html)
self.assertNotIn('data-testid="tag-count-button"', html)
# Get the preview HTML with tags
mock_get_object_tag_counts.return_value = {
str(usage_key): 13
}
html, __ = self._get_container_preview(root_usage_key)
self.assertIn("wrapper-xblock", html)
self.assertIn('data-testid="tag-count-button"', html)
def test_split_test(self):
"""
Test that a split_test block renders all of its children in Studio.

View File

@@ -19,7 +19,7 @@ from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, HttpResponseBadRequest
from django.utils.translation import gettext as _
from edx_django_utils.plugins import pluggable_override
from openedx_tagging.core.tagging import api as tagging_api
from openedx.core.djangoapps.content_tagging.api import get_object_tag_counts
from edx_proctoring.api import (
does_backend_support_onboarding,
get_exam_by_content_id,
@@ -1249,7 +1249,7 @@ def _get_course_unit_tags(course_key) -> dict:
# Create a pattern to match the IDs of the units, e.g. "block-v1:org+course+run+type@vertical+block@*"
vertical_key = course_key.make_usage_key('vertical', 'x')
unit_key_pattern = str(vertical_key).rsplit("@", 1)[0] + "@*"
return tagging_api.get_object_tag_counts(unit_key_pattern)
return get_object_tag_counts(unit_key_pattern, count_implicit=True)
def _was_xblock_ever_exam_linked_with_external(course, xblock):

View File

@@ -4,6 +4,7 @@ general helper functions for xblocks
from opaque_keys.edx.keys import UsageKey
from xmodule.modulestore.django import modulestore
from openedx.core.djangoapps.content_tagging.api import get_object_tag_counts
def usage_key_with_run(usage_key_string):
@@ -13,3 +14,13 @@ def usage_key_with_run(usage_key_string):
usage_key = UsageKey.from_string(usage_key_string)
usage_key = usage_key.replace(course_key=modulestore().fill_in_run(usage_key.course_key))
return usage_key
def get_children_tags_count(xblock):
"""
Returns a map with tag count of each child
"""
children = xblock.get_children()
child_usage_keys = [str(child.location) for child in children]
tags_count_query = ','.join(child_usage_keys)
return get_object_tag_counts(tags_count_query, count_implicit=True)

View File

@@ -32,7 +32,7 @@ function($, _, Backbone, gettext, BasePage,
'click .new-component-button': 'scrollToNewComponentButtons',
'click .save-button': 'saveSelectedLibraryComponents',
'click .paste-component-button': 'pasteComponent',
'click .tags-button': 'openManageTags',
'click .manage-tags-button': 'openManageTags',
'change .header-library-checkbox': 'toggleLibraryComponent',
'click .collapse-button': 'collapseXBlock',
},

View File

@@ -99,6 +99,15 @@ block_is_unit = is_unit(xblock)
<ul class="actions-list nav-dd ui-right">
% if not is_root:
% if can_edit:
% if use_tagging and tags_count:
<li class="action-item">
<button data-tooltip="${_("Manage Tags")}" class="btn-default action-button manage-tags-button" data-testid="tag-count-button">
<span class="icon fa fa-tag" aria-hidden="true"></span>
<span>${tags_count}</span>
<span class="sr action-button-text">${_("Manage Tags")}</span>
</button>
</li>
% endif
% if not show_inline:
<li class="action-item action-edit">
<button class="btn-default edit-button action-button" data-usage-id=${xblock.scope_ids.usage_id}>
@@ -128,7 +137,7 @@ block_is_unit = is_unit(xblock)
% endif
% if use_tagging:
<li class="nav-item">
<a class="tags-button" href="#" role="button">${_("Manage tags")}</a>
<a class="manage-tags-button" href="#" role="button">${_("Manage tags")}</a>
</li>
% endif
% if is_course:

View File

@@ -182,5 +182,6 @@ def tag_content_object(
get_taxonomy = oel_tagging.get_taxonomy
get_taxonomies = oel_tagging.get_taxonomies
get_tags = oel_tagging.get_tags
get_object_tag_counts = oel_tagging.get_object_tag_counts
delete_object_tags = oel_tagging.delete_object_tags
resync_object_tags = oel_tagging.resync_object_tags