feat: display tag counts on course outline page (feature flagged) (#33696)
* feat: display tag counts on outline * fix: taxonomies should default to allow_multiple=True * fix: only load counts once per request * chore: version bump for openedx-learning
This commit is contained in:
@@ -24,6 +24,7 @@ from django.utils.translation import gettext as _
|
||||
from edx_django_utils.plugins import pluggable_override
|
||||
from openedx_events.content_authoring.data import DuplicatedXBlockData
|
||||
from openedx_events.content_authoring.signals import XBLOCK_DUPLICATED
|
||||
from openedx_tagging.core.tagging import api as tagging_api
|
||||
from edx_proctoring.api import (
|
||||
does_backend_support_onboarding,
|
||||
get_exam_by_content_id,
|
||||
@@ -54,6 +55,7 @@ from openedx.core.djangoapps.bookmarks import api as bookmarks_api
|
||||
from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration
|
||||
from openedx.core.djangoapps.video_config.toggles import PUBLIC_VIDEO_SHARE
|
||||
from openedx.core.lib.gating import api as gating_api
|
||||
from openedx.core.lib.cache_utils import request_cached
|
||||
from openedx.core.toggles import ENTRANCE_EXAMS
|
||||
from xmodule.course_block import (
|
||||
DEFAULT_START_DATE,
|
||||
@@ -1400,6 +1402,7 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
|
||||
# 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["tag_counts_by_unit"] = _get_course_unit_tags(xblock.location.context_key)
|
||||
|
||||
xblock_info[
|
||||
"has_partition_group_components"
|
||||
@@ -1414,6 +1417,19 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
|
||||
return xblock_info
|
||||
|
||||
|
||||
@request_cached()
|
||||
def _get_course_unit_tags(course_key) -> dict:
|
||||
"""
|
||||
Get the count of tags that are applied to each unit (vertical) in this course, as a dict.
|
||||
"""
|
||||
if not course_key.is_course:
|
||||
return {} # Unsupported key type, e.g. a library
|
||||
# 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)
|
||||
|
||||
|
||||
def _was_xblock_ever_exam_linked_with_external(course, xblock):
|
||||
"""
|
||||
Determine whether this XBlock is or was ever configured as an external proctored exam.
|
||||
|
||||
@@ -7,6 +7,7 @@ var hasPartitionGroups = xblockInfo.get('has_partition_group_components');
|
||||
var userPartitionInfo = xblockInfo.get('user_partition_info');
|
||||
var selectedGroupsLabel = userPartitionInfo['selected_groups_label'];
|
||||
var selectedPartitionIndex = userPartitionInfo['selected_partition_index'];
|
||||
var tagsCount = (xblockInfo.get('tag_counts_by_unit') || {})[xblockInfo.get('id')] || 0;
|
||||
|
||||
var statusMessages = [];
|
||||
var messageType;
|
||||
@@ -170,11 +171,11 @@ if (is_proctored_exam) {
|
||||
</li>
|
||||
<% } %>
|
||||
|
||||
<% if (xblockInfo.isVertical() && typeof useTaggingTaxonomyListPage !== "undefined" && useTaggingTaxonomyListPage) { %>
|
||||
<% if (xblockInfo.isVertical() && typeof useTaggingTaxonomyListPage !== "undefined" && useTaggingTaxonomyListPage && tagsCount > 0) { %>
|
||||
<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><%- tagsCount %></span>
|
||||
<span class="sr action-button-text"><%- gettext('Manage Tags') %></span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -18,7 +18,7 @@ def create_taxonomy(
|
||||
name: str,
|
||||
description: str | None = None,
|
||||
enabled=True,
|
||||
allow_multiple=False,
|
||||
allow_multiple=True,
|
||||
allow_free_text=False,
|
||||
orgs: list[Organization] | None = None,
|
||||
) -> Taxonomy:
|
||||
|
||||
@@ -20,28 +20,23 @@ class TestTaxonomyMixin:
|
||||
# Taxonomies
|
||||
self.taxonomy_disabled = api.create_taxonomy(
|
||||
name="Learning Objectives",
|
||||
enabled=False,
|
||||
# We will disable this taxonomy below, after we have used it to tag some objects.
|
||||
# Note: "disabled" taxonomies are not a supported nor user-exposed feature at the moment, so it's not
|
||||
# actually that important to test them.
|
||||
)
|
||||
api.set_taxonomy_orgs(self.taxonomy_disabled, orgs=[self.org1, self.org2])
|
||||
self.taxonomy_all_orgs = api.create_taxonomy(
|
||||
name="Content Types",
|
||||
enabled=True,
|
||||
)
|
||||
|
||||
self.taxonomy_all_orgs = api.create_taxonomy(name="Content Types")
|
||||
api.set_taxonomy_orgs(self.taxonomy_all_orgs, all_orgs=True)
|
||||
self.taxonomy_both_orgs = api.create_taxonomy(
|
||||
name="OpenedX/Axim Content Types",
|
||||
enabled=True,
|
||||
)
|
||||
|
||||
self.taxonomy_both_orgs = api.create_taxonomy(name="OpenedX/Axim Content Types")
|
||||
api.set_taxonomy_orgs(self.taxonomy_both_orgs, orgs=[self.org1, self.org2])
|
||||
self.taxonomy_one_org = api.create_taxonomy(
|
||||
name="OpenedX Content Types",
|
||||
enabled=True,
|
||||
)
|
||||
|
||||
self.taxonomy_one_org = api.create_taxonomy(name="OpenedX Content Types")
|
||||
api.set_taxonomy_orgs(self.taxonomy_one_org, orgs=[self.org1])
|
||||
self.taxonomy_no_orgs = api.create_taxonomy(
|
||||
name="No orgs",
|
||||
enabled=True,
|
||||
)
|
||||
|
||||
self.taxonomy_no_orgs = api.create_taxonomy(name="No orgs")
|
||||
|
||||
# Tags
|
||||
self.tag_disabled = Tag.objects.create(
|
||||
taxonomy=self.taxonomy_disabled,
|
||||
@@ -100,6 +95,9 @@ class TestTaxonomyMixin:
|
||||
taxonomy=self.taxonomy_disabled,
|
||||
tags=[self.tag_disabled.value],
|
||||
)[0]
|
||||
self.taxonomy_disabled.enabled = False
|
||||
self.taxonomy_disabled.save()
|
||||
self.disabled_course_tag.refresh_from_db() # Update its cached .taxonomy
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -184,7 +182,6 @@ class TestAPITaxonomy(TestTaxonomyMixin, TestCase):
|
||||
assert valid_tags[0].id == object_tag.id
|
||||
|
||||
@ddt.data(
|
||||
("taxonomy_disabled", "disabled_course_tag"),
|
||||
("taxonomy_all_orgs", "all_orgs_course_tag"),
|
||||
("taxonomy_all_orgs", "all_orgs_block_tag"),
|
||||
("taxonomy_both_orgs", "both_orgs_course_tag"),
|
||||
|
||||
@@ -599,7 +599,7 @@ class TestRulesTaxonomy(TestTaxonomyMixin, TestCase):
|
||||
|
||||
def test_view_object_tag_diabled(self):
|
||||
"""
|
||||
Noboty can view a ObjectTag from a disable taxonomy
|
||||
Nobody can view a ObjectTag from a disabled taxonomy
|
||||
"""
|
||||
perm = "oel_tagging.view_objecttag"
|
||||
assert self.superuser.has_perm(perm, self.disabled_course_tag)
|
||||
|
||||
@@ -121,7 +121,7 @@ libsass==0.10.0
|
||||
click==8.1.6
|
||||
|
||||
# pinning this version to avoid updates while the library is being developed
|
||||
openedx-learning==0.3.3
|
||||
openedx-learning==0.3.4
|
||||
|
||||
# lti-consumer-xblock 9.6.2 contains a breaking change that makes
|
||||
# existing custom parameter configurations unusable.
|
||||
|
||||
@@ -802,7 +802,7 @@ openedx-filters==1.6.0
|
||||
# via
|
||||
# -r requirements/edx/kernel.in
|
||||
# lti-consumer-xblock
|
||||
openedx-learning==0.3.3
|
||||
openedx-learning==0.3.4
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/kernel.in
|
||||
|
||||
@@ -1330,7 +1330,7 @@ openedx-filters==1.6.0
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
# lti-consumer-xblock
|
||||
openedx-learning==0.3.3
|
||||
openedx-learning==0.3.4
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
|
||||
@@ -960,7 +960,7 @@ openedx-filters==1.6.0
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# lti-consumer-xblock
|
||||
openedx-learning==0.3.3
|
||||
openedx-learning==0.3.4
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
|
||||
@@ -1005,7 +1005,7 @@ openedx-filters==1.6.0
|
||||
# via
|
||||
# -r requirements/edx/base.txt
|
||||
# lti-consumer-xblock
|
||||
openedx-learning==0.3.3
|
||||
openedx-learning==0.3.4
|
||||
# via
|
||||
# -c requirements/edx/../constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
|
||||
Reference in New Issue
Block a user