Skip to content

Commit

Permalink
feat: Tag count in components on Studio Unit page(#33928)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisChV authored Jan 12, 2024
1 parent 019888f commit 90879d1
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 7 deletions.
13 changes: 11 additions & 2 deletions cms/djangoapps/contentstore/views/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
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,
Expand All @@ -51,7 +51,10 @@
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__ = [
Expand Down Expand Up @@ -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(
Expand All @@ -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)
Expand Down
7 changes: 6 additions & 1 deletion cms/djangoapps/contentstore/views/preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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")
Expand Down
33 changes: 33 additions & 0 deletions cms/djangoapps/contentstore/views/tests/test_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
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
Expand Down Expand Up @@ -83,6 +84,7 @@
add_container_page_publishing_info,
create_xblock_info,
)
from cms.djangoapps.contentstore.toggles import ENABLE_TAGGING_TAXONOMY_LIST_PAGE


class AsideTest(XBlockAside):
Expand Down Expand Up @@ -269,6 +271,37 @@ def test_get_container_nested_container_fragment(self):
),
)

@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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
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,
Expand Down Expand Up @@ -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):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

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):
Expand All @@ -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)
2 changes: 1 addition & 1 deletion cms/static/js/views/pages/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
},
Expand Down
11 changes: 10 additions & 1 deletion cms/templates/studio_xblock_wrapper.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@
<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}>
Expand Down Expand Up @@ -128,7 +137,7 @@
% 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:
Expand Down
1 change: 1 addition & 0 deletions openedx/core/djangoapps/content_tagging/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 90879d1

Please sign in to comment.