Added edxnotes information to the courseware API.

Added notes visibility toggle support for courseware MFE.
Removed notes and calculator from chromeless view when rendered in courseware MFE.
This commit is contained in:
Dave St.Germain
2020-04-03 13:30:47 -04:00
parent 4afefdf38c
commit 543611fbb7
6 changed files with 69 additions and 28 deletions

View File

@@ -1682,7 +1682,8 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True):
'staff_access': bool(request.user.has_perm(VIEW_XQA_INTERFACE, course)),
'xqa_server': settings.FEATURES.get('XQA_SERVER', 'http://your_xqa_server.com'),
'display_reset_dates_banner': display_reset_dates_banner,
'web_app_course_url': reverse(COURSE_HOME_VIEW_NAME, args=[course.id])
'web_app_course_url': reverse(COURSE_HOME_VIEW_NAME, args=[course.id]),
'is_learning_mfe': request.META.get('HTTP_REFERER', '').startswith(settings.LEARNING_MICROFRONTEND_URL),
}
return render_to_response('courseware/courseware-chromeless.html', context)

View File

@@ -12,13 +12,17 @@
errorMessage: gettext('An error has occurred. Make sure that you are connected to the Internet, and then try refreshing the page.'),
initialize: function(options) {
_.bindAll(this, 'onSuccess', 'onError', 'keyDownToggleHandler');
_.bindAll(this, 'onSuccess', 'onError', 'keyDownToggleHandler', 'receiveMessage');
this.visibility = options.visibility;
this.visibilityUrl = options.visibilityUrl;
this.label = this.$('.utility-control-label');
this.actionLink = this.$('.action-toggle-notes');
this.actionLink.removeClass('is-disabled');
this.actionToggleMessage = this.$('.action-toggle-message');
if (options.hideUI) {
$(window).on('message', this.receiveMessage);
}
this.notification = new Annotator.Notification();
$(document).on('keydown.edxnotes:togglenotes', this.keyDownToggleHandler);
},
@@ -28,6 +32,18 @@
Backbone.View.prototype.remove.call(this);
},
receiveMessage: function(event) {
var data = event.originalEvent.data;
if (data === 'tools.toggleNotes') {
event.preventDefault();
this.visibility = !this.visibility;
if (this.visibility) {
this.enableNotes();
} else {
this.disableNotes();
}
}
},
toggleHandler: function(event) {
event.preventDefault();
this.visibility = !this.visibility;
@@ -94,11 +110,12 @@
});
return {
ToggleVisibilityView: function(visibility, visibilityUrl) {
ToggleVisibilityView: function(visibility, visibilityUrl, hideUI) {
return new ToggleVisibilityView({
el: $('.edx-notes-visibility').get(0),
visibility: visibility,
visibilityUrl: visibilityUrl
visibilityUrl: visibilityUrl,
hideUI: hideUI
});
},
VisibilityDecorator: VisibilityDecorator

View File

@@ -46,29 +46,23 @@ ${static.get_page_title_breadcrumbs(course_name())}
<%static:css group='style-student-notes'/>
% endif
<script type="text/javascript" src="${static.url('js/jquery.autocomplete.js')}"></script>
<script type="text/javascript" src="${static.url('js/src/tooltip_manager.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.autocomplete.js')}" async></script>
<script type="text/javascript" src="${static.url('js/src/tooltip_manager.js')}" async></script>
<link href="${static.url('css/vendor/jquery.autocomplete.css')}" rel="stylesheet" type="text/css">
<link href="${static.url('css/vendor/jquery.autocomplete.css')}" rel="preload" type="text/css">
${HTML(fragment.head_html())}
<script type="text/javascript">
// If this chromeless view is in an iframe in the learning microfrontend app
// then add a base tag in the head (of the iframe document) to force links
// in this iframe to navigate the parent window.
var learningAppUrl = "${settings.LEARNING_MICROFRONTEND_URL | n, js_escaped_string}";
var parentIsLearningApp = document.referrer.indexOf(learningAppUrl) === 0;
if (window !== window.parent && parentIsLearningApp) {
var baseElement = document.createElement('base');
baseElement.setAttribute('target', '_parent');
document.head.appendChild(baseElement);
}
</script>
% if is_learning_mfe:
## If this chromeless view is in an iframe in the learning microfrontend app
## then add a base tag in the head (of the iframe document) to force links
## in this iframe to navigate the parent window.
<base target="_parent">
%endif
</%block>
<%block name="js_extra">
<script type="text/javascript" src="${static.url('common/js/vendor/jquery.scrollTo.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
<script type="text/javascript" src="${static.url('common/js/vendor/jquery.scrollTo.js')}" async></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}" async></script>
<%static:js group='courseware'/>
@@ -99,7 +93,9 @@ ${HTML(fragment.foot_html())}
</main>
</section>
</div>
% if course.show_calculator or edx_notes_enabled:
% if not is_learning_mfe:
% if course.show_calculator or edx_notes_enabled:
<nav class="nav-utilities ${"has-utility-calculator" if course.show_calculator else ""}" aria-label="${_('Course Utilities')}">
## Utility: Notes
% if edx_notes_enabled:
@@ -111,17 +107,20 @@ ${HTML(fragment.foot_html())}
<%include file="/calculator/toggle_calculator.html" />
% endif
</nav>
% endif
% else:
% if edx_notes_enabled:
<%include file="/edxnotes/toggle_notes.html" args="course=course"/>
% endif
% endif
% if is_learning_mfe:
<script type="text/javascript">
(function() {
// If this view is rendered in an iframe within the learning microfrontend app
// it will report the height of its contents to the parent window when the
// document loads, window resizes, or DOM mutates.
var learningAppUrl = "${settings.LEARNING_MICROFRONTEND_URL | n, js_escaped_string}";
var parentIsLearningApp = document.referrer.indexOf(learningAppUrl) === 0;
if (window !== window.parent && parentIsLearningApp) {
if (window !== window.parent) {
var lastHeight = window.offsetHeight;
var lastWidth = window.offsetWidth;
var contentElement = document.getElementById('content');
@@ -166,3 +165,4 @@ ${HTML(fragment.foot_html())}
}
}());
</script>
% endif

View File

@@ -9,8 +9,12 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_str
<%
edxnotes_visibility = course.edxnotes_visibility
edxnotes_visibility_url = reverse("edxnotes_visibility", kwargs={"course_id": course.id})
if is_learning_mfe is UNDEFINED:
hide_ui = False
else:
hide_ui = is_learning_mfe
%>
<div class="wrapper-utility edx-notes-visibility">
<div class="wrapper-utility edx-notes-visibility ${'hidden' if hide_ui else ''}">
<span class="action-toggle-message" aria-live="polite"></span>
<button class="utility-control utility-control-button action-toggle-notes is-disabled ${"is-active" if edxnotes_visibility else ""}">
<span class="icon fa fa-pencil" aria-hidden="true"></span>
@@ -25,6 +29,7 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_str
<%static:require_module_async module_name="js/edxnotes/views/notes_visibility_factory" class_name="NotesVisibilityFactory">
NotesVisibilityFactory.ToggleVisibilityView(
${edxnotes_visibility | n, dump_js_escaped_json},
'${edxnotes_visibility_url | n, js_escaped_string}'
'${edxnotes_visibility_url | n, js_escaped_string}',
${hide_ui | n, dump_js_escaped_json}
);
</%static:require_module_async>

View File

@@ -838,6 +838,13 @@ class CourseOverview(TimeStampedModel):
"""
return self._original_course.show_calculator
@property
def edxnotes_visibility(self):
"""
TODO: move this to the model.
"""
return self._original_course.edxnotes_visibility
def __str__(self):
"""Represent ourselves with the course key."""
return six.text_type(self.id)

View File

@@ -8,6 +8,7 @@ from django.urls import reverse
from rest_framework import serializers
from course_modes.models import CourseMode
from edxnotes.helpers import is_feature_enabled
from lms.djangoapps.courseware.tabs import get_course_tab_list
from lms.djangoapps.courseware.utils import verified_upgrade_deadline_link
@@ -88,6 +89,7 @@ class CourseInfoSerializer(serializers.Serializer): # pylint: disable=abstract-
show_calculator = serializers.BooleanField()
is_staff = serializers.BooleanField()
can_load_courseware = serializers.BooleanField()
notes = serializers.SerializerMethodField()
# TODO: TNL-7053 Legacy: Delete these two once ready to contract
user_has_access = serializers.BooleanField()
@@ -134,3 +136,12 @@ class CourseInfoSerializer(serializers.Serializer): # pylint: disable=abstract-
'sku': mode.sku,
'upgrade_url': verified_upgrade_deadline_link(course_overview.effective_user, course_overview),
}
def get_notes(self, course_overview):
"""
Return whether edxnotes is enabled and visible.
"""
return {
'enabled': is_feature_enabled(course_overview, course_overview.effective_user),
'visible': course_overview.edxnotes_visibility,
}