From 5a2998fb5ba9dcb67fef4874c2e0271b494df0ab Mon Sep 17 00:00:00 2001 From: Harry Rein Date: Thu, 6 Jul 2017 16:48:57 -0400 Subject: [PATCH] Allowing writing of reviews on reviews page. LEARNER-1628 This allows enrolled users to write reviews on the reviews page that can be accessed through the course tools sidebar. A button in the top corner of the page toggles the widget that is configured with a setting in the common.py file. The reviews tool is Course Talk. --- lms/envs/common.py | 4 +++ .../sass/features/_course-experience.scss | 19 ++++++++++-- .../course_experience/js/CourseTalkReviews.js | 31 +++++++++++++++++++ .../course_experience/js/WelcomeMessage.js | 4 +-- .../js/spec/WelcomeMessage_spec.js | 2 +- .../course-reviews-fragment.html | 7 +++-- .../coursetalk-reviews-fragment.html | 14 +++++++-- .../welcome-message-fragment.html | 6 ++-- .../course_experience/views/course_reviews.py | 10 ++++-- webpack.config.js | 1 + 10 files changed, 83 insertions(+), 15 deletions(-) create mode 100644 openedx/features/course_experience/static/course_experience/js/CourseTalkReviews.js diff --git a/lms/envs/common.py b/lms/envs/common.py index 5f3ab59669..b0fea16b84 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -398,6 +398,10 @@ FEATURES = { COURSE_REVIEWS_TOOL_PROVIDER_FRAGMENT_NAME = 'coursetalk-reviews-fragment.html' COURSE_REVIEWS_TOOL_PROVIDER_PLATFORM_KEY = 'edx' +# CDN links to CourseTalk scripts to load read and write widgets +COURSE_TALK_READ_ONLY_SOURCE = '//d3q6qq2zt8nhwv.cloudfront.net/s/js/widgets/coursetalk-read-reviews.js' +COURSE_TALK_WRITE_ONLY_SOURCE = '//d3q6qq2zt8nhwv.cloudfront.net/s/js/widgets/coursetalk-write-reviews.js' + # Ignore static asset files on import which match this pattern ASSET_IGNORE_REGEX = r"(^\._.*$)|(^\.DS_Store$)|(^.*~$)" diff --git a/lms/static/sass/features/_course-experience.scss b/lms/static/sass/features/_course-experience.scss index 3ecb26aca8..ce505d6955 100644 --- a/lms/static/sass/features/_course-experience.scss +++ b/lms/static/sass/features/_course-experience.scss @@ -200,6 +200,21 @@ } // Course Reviews Page -.course-reviews-tool { - margin: ($baseline * 2) ($baseline * 3); +.course-reviews { + .page-header.has-secondary > .page-header-main { + display: block; + position: relative; + + .toggle-read-write-reviews { + position: absolute; + top: $baseline * (-1/2); + right: $baseline / 2; + cursor: pointer; + } + } + + .course-reviews-tool { + margin: ($baseline * 2) ($baseline * 3); + position: relative; + } } diff --git a/openedx/features/course_experience/static/course_experience/js/CourseTalkReviews.js b/openedx/features/course_experience/static/course_experience/js/CourseTalkReviews.js new file mode 100644 index 0000000000..fd197b2e40 --- /dev/null +++ b/openedx/features/course_experience/static/course_experience/js/CourseTalkReviews.js @@ -0,0 +1,31 @@ +/** + Enable users to switch between viewing and writing CourseTalk reviews. + */ + +export class CourseTalkReviews { // eslint-disable-line import/prefer-default-export + constructor(options) { + const $courseTalkToggleReadWriteReviews = $(options.toggleButton); + + const toReadBtnText = 'View Reviews'; + const toWriteBtnText = 'Write a Review'; + + // Initialize page to the read reviews view + self.currentSrc = options.readSrc; + $.getScript(options.readSrc); + $courseTalkToggleReadWriteReviews.text(toWriteBtnText); + + $courseTalkToggleReadWriteReviews.on('click', () => { + // Cache js file for future button clicks + $.ajaxSetup({ cache: true }); + + // Toggle the new coursetalk script object + const switchToReadView = self.currentSrc === options.writeSrc; + self.currentSrc = switchToReadView ? options.readSrc : options.writeSrc; + $.getScript(self.currentSrc); + + // Toggle button text on switch to the other view + const newText = switchToReadView ? toWriteBtnText : toReadBtnText; + $courseTalkToggleReadWriteReviews.text(newText); + }); + } +} diff --git a/openedx/features/course_experience/static/course_experience/js/WelcomeMessage.js b/openedx/features/course_experience/static/course_experience/js/WelcomeMessage.js index 52c948c3a2..3265673215 100644 --- a/openedx/features/course_experience/static/course_experience/js/WelcomeMessage.js +++ b/openedx/features/course_experience/static/course_experience/js/WelcomeMessage.js @@ -3,11 +3,11 @@ import 'jquery.cookie'; export class WelcomeMessage { // eslint-disable-line import/prefer-default-export - constructor(dismissUrl) { + constructor(options) { $('.dismiss-message button').click(() => { $.ajax({ type: 'POST', - url: dismissUrl, + url: options.dismissUrl, headers: { 'X-CSRFToken': $.cookie('csrftoken'), }, diff --git a/openedx/features/course_experience/static/course_experience/js/spec/WelcomeMessage_spec.js b/openedx/features/course_experience/static/course_experience/js/spec/WelcomeMessage_spec.js index 6c7129e05e..cf1a99d891 100644 --- a/openedx/features/course_experience/static/course_experience/js/spec/WelcomeMessage_spec.js +++ b/openedx/features/course_experience/static/course_experience/js/spec/WelcomeMessage_spec.js @@ -13,7 +13,7 @@ describe('Welcome Message factory', () => { beforeEach(() => { loadFixtures('course_experience/fixtures/welcome-message-fragment.html'); - new WelcomeMessage(endpointUrl); // eslint-disable-line no-new + new WelcomeMessage({ dismissUrl: endpointUrl }); // eslint-disable-line no-new }); it('When button click is made, ajax call is made and message is hidden.', () => { diff --git a/openedx/features/course_experience/templates/course_experience/course-reviews-fragment.html b/openedx/features/course_experience/templates/course_experience/course-reviews-fragment.html index a0ef0bd8e0..8044c04cc0 100644 --- a/openedx/features/course_experience/templates/course_experience/course-reviews-fragment.html +++ b/openedx/features/course_experience/templates/course_experience/course-reviews-fragment.html @@ -27,11 +27,14 @@ from openedx.features.course_experience import course_home_page_title + % if is_enrolled: +
+ % endif
- % if course_reviews_provider_fragment: - ${HTML(course_reviews_provider_fragment.body_html())} + % if course_reviews_fragment: + ${HTML(course_reviews_fragment.body_html())} % endif
diff --git a/openedx/features/course_experience/templates/course_experience/course_reviews_modules/coursetalk-reviews-fragment.html b/openedx/features/course_experience/templates/course_experience/course_reviews_modules/coursetalk-reviews-fragment.html index 0409a80d2b..258f46a867 100644 --- a/openedx/features/course_experience/templates/course_experience/course_reviews_modules/coursetalk-reviews-fragment.html +++ b/openedx/features/course_experience/templates/course_experience/course_reviews_modules/coursetalk-reviews-fragment.html @@ -2,9 +2,11 @@ <%page expression_filter="h"/> -<%namespace name='static' file='../static_content.html'/> +<%namespace name='static' file='../../static_content.html'/> <%! +from django.conf import settings +from openedx.core.djangolib.js_utils import js_escaped_string from openedx.features.course_experience import SHOW_REVIEWS_TOOL_FLAG %> @@ -13,6 +15,12 @@ from openedx.features.course_experience import SHOW_REVIEWS_TOOL_FLAG ## Coursetalk Widget
- - % endif + +<%static:webpack entry="CourseTalkReviews"> + new CourseTalkReviews({ + toggleButton: '.toggle-read-write-reviews', + readSrc: "${settings.COURSE_TALK_READ_ONLY_SOURCE | n, js_escaped_string}", + writeSrc: "${settings.COURSE_TALK_WRITE_ONLY_SOURCE | n, js_escaped_string}" + }); + diff --git a/openedx/features/course_experience/templates/course_experience/welcome-message-fragment.html b/openedx/features/course_experience/templates/course_experience/welcome-message-fragment.html index 1c1ea9d228..ff9dbe4580 100644 --- a/openedx/features/course_experience/templates/course_experience/welcome-message-fragment.html +++ b/openedx/features/course_experience/templates/course_experience/welcome-message-fragment.html @@ -4,8 +4,8 @@ <%namespace name='static' file='../static_content.html'/> <%! -from openedx.core.djangolib.js_utils import js_escaped_string from django.utils.translation import ugettext as _ +from openedx.core.djangolib.js_utils import js_escaped_string from openedx.core.djangolib.markup import HTML %> @@ -20,5 +20,7 @@ from openedx.core.djangolib.markup import HTML <%static:webpack entry="WelcomeMessage"> - new WelcomeMessage("${dismiss_url | n, js_escaped_string}"); + new WelcomeMessage({ + dismissUrl: "${dismiss_url | n, js_escaped_string}", + }); diff --git a/openedx/features/course_experience/views/course_reviews.py b/openedx/features/course_experience/views/course_reviews.py index ad86a7087e..08ac07fd88 100644 --- a/openedx/features/course_experience/views/course_reviews.py +++ b/openedx/features/course_experience/views/course_reviews.py @@ -11,6 +11,7 @@ from opaque_keys.edx.keys import CourseKey from web_fragments.fragment import Fragment from courseware.courses import get_course_with_access +from student.models import CourseEnrollment from lms.djangoapps.courseware.views.views import CourseTabView from openedx.core.djangoapps.plugin_api.views import EdxFragmentView from openedx.features.course_experience import default_course_url_name @@ -45,12 +46,14 @@ class CourseReviewsFragmentView(EdxFragmentView): """ course_key = CourseKey.from_string(course_id) - course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True) + course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False) course_url_name = default_course_url_name(course.id) course_url = reverse(course_url_name, kwargs={'course_id': unicode(course.id)}) + is_enrolled = CourseEnrollment.is_enrolled(request.user, course.id) + # Create the fragment - course_reviews_provider_fragment = CourseReviewsModuleFragmentView().render_to_fragment( + course_reviews_fragment = CourseReviewsModuleFragmentView().render_to_fragment( request, course=course, **kwargs @@ -59,7 +62,8 @@ class CourseReviewsFragmentView(EdxFragmentView): context = { 'course': course, 'course_url': course_url, - 'course_reviews_provider_fragment': course_reviews_provider_fragment + 'course_reviews_fragment': course_reviews_fragment, + 'is_enrolled': is_enrolled, } html = render_to_string('course_experience/course-reviews-fragment.html', context) diff --git a/webpack.config.js b/webpack.config.js index 88f9810aa0..f6f78bde2b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,6 +20,7 @@ var wpconfig = { entry: { CourseOutline: './openedx/features/course_experience/static/course_experience/js/CourseOutline.js', CourseSock: './openedx/features/course_experience/static/course_experience/js/CourseSock.js', + CourseTalkReviews: './openedx/features/course_experience/static/course_experience/js/CourseTalkReviews.js', WelcomeMessage: './openedx/features/course_experience/static/course_experience/js/WelcomeMessage.js', Import: './cms/static/js/features/import/factories/import.js' },