Skip to content

Commit

Permalink
feat: Tag sections, subsections, and the whole course (openedx#34690)
Browse files Browse the repository at this point in the history
(In the legacy UI, if the 'new_studio_mfe.use_tagging_taxonomy_list_page' waffle flag is enabled)
  • Loading branch information
yusuf-musleh authored and andrey-canon committed May 16, 2024
1 parent 534d275 commit 4e855ee
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 19 deletions.
28 changes: 21 additions & 7 deletions cms/djangoapps/contentstore/views/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -1394,7 +1394,8 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F
# 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["course_tags_count"] = _get_course_tags_count(course.id)
xblock_info["tag_counts_by_block"] = _get_course_block_tags(xblock.location.context_key)

xblock_info['user_partition_info'] = get_visibility_partition_info(xblock, course=course)

Expand Down Expand Up @@ -1642,16 +1643,29 @@ def _xblock_type_and_display_name(xblock):


@request_cached()
def _get_course_unit_tags(course_key) -> dict:
def _get_course_tags_count(course_key) -> dict:
"""
Get the count of tags that are applied to each unit (vertical) in this course, as a dict.
Get the count of tags that are applied to the course as a dict: {course_key: tags_count}
"""
if not course_key.is_course:
return {} # Unsupported key type

return get_object_tag_counts(str(course_key), count_implicit=True)


@request_cached()
def _get_course_block_tags(course_key) -> dict:
"""
Get the count of tags that are applied to each block 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 get_object_tag_counts(unit_key_pattern, count_implicit=True)

# Create a pattern to match the IDs of all blocks, e.g. "block-v1:org+course+run+type@*"
catch_all_key = course_key.make_usage_key("*", "x")
catch_all_key_pattern = str(catch_all_key).rsplit("@*", 1)[0] + "@*"

return get_object_tag_counts(catch_all_key_pattern, count_implicit=True)


def get_children_tags_count(xblock):
Expand Down
54 changes: 54 additions & 0 deletions cms/static/js/views/course_manage_tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
define([
'jquery', 'underscore', 'backbone', 'js/utils/templates',
'edx-ui-toolkit/js/utils/html-utils', 'js/views/utils/tagging_drawer_utils',
'js/views/tag_count', 'js/models/tag_count'],
function(
$, _, Backbone, TemplateUtils, HtmlUtils, TaggingDrawerUtils, TagCountView, TagCountModel
) {
'use strict';

var CourseManageTagsView = Backbone.View.extend({
events: {
'click .manage-tags-button': 'openManageTagsDrawer',
},

initialize: function() {
this.template = TemplateUtils.loadTemplate('course-manage-tags');
this.courseId = course.id;
},

openManageTagsDrawer: function(event) {
const taxonomyTagsWidgetUrl = this.model.get('taxonomy_tags_widget_url');
const contentId = this.courseId;
TaggingDrawerUtils.openDrawer(taxonomyTagsWidgetUrl, contentId);
},

renderTagCount: function() {
const contentId = this.courseId;
const tagCountsForCourse = this.model.get('course_tags_count');
const tagsCount = tagCountsForCourse !== undefined ? tagCountsForCourse[contentId] : 0;
var countModel = new TagCountModel({
content_id: contentId,
tags_count: tagsCount,
course_authoring_url: this.model.get('course_authoring_url'),
}, {parse: true});
var tagCountView = new TagCountView({el: this.$('.tag-count'), model: countModel});
tagCountView.setupMessageListener();
tagCountView.render();
this.$('.tag-count').click((event) => {
event.preventDefault();
this.openManageTagsDrawer();
});
},

render: function() {
var html = this.template(this.model.attributes);
HtmlUtils.setHtml(this.$el, HtmlUtils.HTML(html));
this.renderTagCount();
return this;
}
});

return CourseManageTagsView;
}
);
13 changes: 9 additions & 4 deletions cms/static/js/views/course_outline.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,22 @@ function(

renderTagCount: function() {
const contentId = this.model.get('id');
const tagCountsByUnit = this.model.get('tag_counts_by_unit')
const tagsCount = tagCountsByUnit !== undefined ? tagCountsByUnit[contentId] : 0
const tagCountsByBlock = this.model.get('tag_counts_by_block')
// Skip the course block since that is handled elsewhere in course_manage_tags
if (contentId.includes('@course')) {
return
}
const tagsCount = tagCountsByBlock !== undefined ? tagCountsByBlock[contentId] : 0
const tagCountElem = this.$(`.tag-count[data-locator="${contentId}"]`);
var countModel = new TagCountModel({
content_id: contentId,
tags_count: tagsCount,
course_authoring_url: this.model.get('course_authoring_url'),
}, {parse: true});
var tagCountView = new TagCountView({el: this.$('.tag-count'), model: countModel});
var tagCountView = new TagCountView({el: tagCountElem, model: countModel});
tagCountView.setupMessageListener();
tagCountView.render();
this.$('.tag-count').click((event) => {
tagCountElem.click((event) => {
event.preventDefault();
this.openManageTagsDrawer();
});
Expand Down
14 changes: 12 additions & 2 deletions cms/static/js/views/pages/course_outline.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
define([
'jquery', 'underscore', 'gettext', 'js/views/pages/base_page', 'js/views/utils/xblock_utils',
'js/views/course_outline', 'common/js/components/utils/view_utils', 'common/js/components/views/feedback_alert',
'common/js/components/views/feedback_notification', 'js/views/course_highlights_enable'],
'common/js/components/views/feedback_notification', 'js/views/course_highlights_enable', 'js/views/course_manage_tags'],
function($, _, gettext, BasePage, XBlockViewUtils, CourseOutlineView, ViewUtils, AlertView, NoteView,
CourseHighlightsEnableView
CourseHighlightsEnableView,
CourseManageTagsView
) {
'use strict';
var expandedLocators, CourseOutlinePage;
Expand Down Expand Up @@ -93,6 +94,15 @@ function($, _, gettext, BasePage, XBlockViewUtils, CourseOutlineView, ViewUtils,
this.highlightsEnableView.render();
}

// if tagging enabled
if (this.model.get('use_tagging_taxonomy_list_page')) {
this.courseManageTagsView = new CourseManageTagsView({
el: this.$('.status-manage-tags'),
model: this.model
});
this.courseManageTagsView.render();
}

this.outlineView = new this.outlineViewClass({
el: this.$('.outline'),
model: this.model,
Expand Down
13 changes: 10 additions & 3 deletions cms/static/sass/views/_outline.scss
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@

.status-release,
.status-highlights-enabled,
.status-manage-tags,
.status-studio-frontend {
@extend %t-copy-base;

Expand All @@ -200,29 +201,35 @@
}
}

.status-highlights-enabled {
.status-highlights-enabled,
.status-manage-tags {
vertical-align: top;
}

.status-release-label,
.status-release-value,
.status-highlights-enabled-label,
.status-course-manage-tags-label,
.status-highlights-enabled-value,
.status-course-manage-tags-value,
.status-highlights-enabled-info,
.status-course-manage-tags-info,
.status-actions {
display: inline-block;
vertical-align: middle;
margin-bottom: 0;
}

.status-release-value,
.status-highlights-enabled-value {
.status-highlights-enabled-value,
.status-course-manage-tags-value {
@extend %t-strong;

font-size: smaller;
}

.status-highlights-enabled-info {
.status-highlights-enabled-info,
.status-course-manage-tags-info {
font-size: smaller;
margin-left: $baseline / 2;
}
Expand Down
3 changes: 2 additions & 1 deletion cms/templates/course_outline.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

<%block name="header_extras">
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" />
% for template_name in ['course-outline', 'xblock-string-field-editor', 'basic-modal', 'modal-button', 'course-outline-modal', 'due-date-editor', 'self-paced-due-date-editor', 'release-date-editor', 'grading-editor', 'publish-editor', 'staff-lock-editor', 'unit-access-editor', 'discussion-editor', 'content-visibility-editor', 'verification-access-editor', 'timed-examination-preference-editor', 'access-editor', 'settings-modal-tabs', 'show-correctness-editor', 'highlights-editor', 'highlights-enable-editor', 'course-highlights-enable', 'tag-count']:
% for template_name in ['course-outline', 'xblock-string-field-editor', 'basic-modal', 'modal-button', 'course-outline-modal', 'due-date-editor', 'self-paced-due-date-editor', 'release-date-editor', 'grading-editor', 'publish-editor', 'staff-lock-editor', 'unit-access-editor', 'discussion-editor', 'content-visibility-editor', 'verification-access-editor', 'timed-examination-preference-editor', 'access-editor', 'settings-modal-tabs', 'show-correctness-editor', 'highlights-editor', 'highlights-enable-editor', 'course-highlights-enable', 'course-manage-tags', 'tag-count']:
<script type="text/template" id="${template_name}-tpl">
<%static:include path="js/${template_name}.underscore" />
</script>
Expand Down Expand Up @@ -269,6 +269,7 @@ <h3 class="sr">${_("Page Actions")}</h3>
</%static:studiofrontend>
</div>
<div class="status-highlights-enabled"></div>
<div class="status-manage-tags"></div>
</div>
<div class="wrapper-dnd"
% if getattr(context_course, 'language'):
Expand Down
8 changes: 8 additions & 0 deletions cms/templates/js/course-manage-tags.underscore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="course-manage-tags-container">
<h2 class="status-course-manage-tags-label">
<%- gettext('Course tags') %>
</h2>
<br>
<span class="status-course-manage-tags-value tag-count" data-locator="<%- course.id %>"></span>
<a class="status-course-manage-tags-info manage-tags-button" href="#"><%- gettext('Manage tags') %></a>
</div>
4 changes: 2 additions & 2 deletions cms/templates/js/course-outline.underscore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var userPartitionInfo = xblockInfo.get('user_partition_info');
var selectedGroupsLabel = userPartitionInfo['selected_groups_label'];
var selectedPartitionIndex = userPartitionInfo['selected_partition_index'];
var xblockId = xblockInfo.get('id')
var tagsCount = (xblockInfo.get('tag_counts_by_unit') || {})[xblockId] || 0;
var tagsCount = (xblockInfo.get('tag_counts_by_block') || {})[xblockId] || 0;

var statusMessages = [];
var messageType;
Expand Down Expand Up @@ -190,7 +190,7 @@ if (is_proctored_exam) {
</li>
<% } %>

<% if (xblockInfo.isVertical() && typeof useTaggingTaxonomyListPage !== "undefined" && useTaggingTaxonomyListPage) { %>
<% if (typeof useTaggingTaxonomyListPage !== "undefined" && useTaggingTaxonomyListPage) { %>
<li class="action-item tag-count" data-locator="<%- xblockId %>"></li>
<% } %>

Expand Down
7 changes: 7 additions & 0 deletions cms/templates/js/tag-count.underscore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@
<span><%- tags_count %></span>
<span class="sr action-button-text"><%- gettext("Manage Tags") %></span>
</button>
<% } else { %>
<button data-tooltip="<%- gettext("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>?</span>
<span class="sr action-button-text"><%- gettext("Manage Tags") %></span>
</button>
<% } %>

0 comments on commit 4e855ee

Please sign in to comment.