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:
Braden MacDonald
2023-11-16 10:03:13 -08:00
committed by GitHub
parent e5386df557
commit ed379926c2
10 changed files with 41 additions and 27 deletions

View File

@@ -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.

View File

@@ -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>

View File

@@ -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:

View File

@@ -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"),

View File

@@ -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)

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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