diff --git a/lms/djangoapps/django_comment_client/base/urls.py b/lms/djangoapps/django_comment_client/base/urls.py index ac830af6cc..f2cb4ccb15 100644 --- a/lms/djangoapps/django_comment_client/base/urls.py +++ b/lms/djangoapps/django_comment_client/base/urls.py @@ -4,6 +4,7 @@ import django_comment_client.base.views urlpatterns = patterns('django_comment_client.base.views', url(r'upload$', 'upload', name='upload'), + url(r'users/(?P\w+)/update_moderator_status$', 'update_moderator_status', name='update_moderator_status'), url(r'threads/tags/autocomplete$', 'tags_autocomplete', name='tags_autocomplete'), url(r'threads/(?P[\w\-]+)/update$', 'update_thread', name='update_thread'), url(r'threads/(?P[\w\-]+)/reply$', 'create_comment', name='create_comment'), diff --git a/lms/djangoapps/django_comment_client/base/views.py b/lms/djangoapps/django_comment_client/base/views.py index 0890ccac0e..1092b6cbed 100644 --- a/lms/djangoapps/django_comment_client/base/views.py +++ b/lms/djangoapps/django_comment_client/base/views.py @@ -4,8 +4,10 @@ import os import os.path import logging import urlparse +import functools import comment_client as cc +import django_comment_client.utils as utils from django.core import exceptions from django.contrib.auth.decorators import login_required @@ -14,13 +16,15 @@ from django.views.decorators import csrf from django.core.files.storage import get_storage_class from django.utils.translation import ugettext as _ from django.conf import settings +from django.contrib.auth.models import User from mitxmako.shortcuts import render_to_response, render_to_string +from courseware.courses import check_course + from django_comment_client.utils import JsonResponse, JsonError, extract -import django_comment_client.utils as utils from django_comment_client.permissions import check_permissions_by_view -import functools +from django_comment_client.models import Role def permitted(fn): @functools.wraps(fn) @@ -113,6 +117,7 @@ def _create_comment(request, course_id, thread_id=None, parent_id=None): if request.is_ajax(): context = { 'comment': comment.to_dict(), + 'course_id': course_id, } html = render_to_string('discussion/ajax_create_comment.html', context) annotated_content_info = utils.get_annotated_content_info(course_id, @@ -289,6 +294,36 @@ def unfollow_user(request, course_id, followed_user_id): user.unfollow(followed_user) return JsonResponse({}) +@require_POST +@login_required +@permitted +def update_moderator_status(request, course_id, user_id): + is_moderator = request.POST.get('is_moderator', '').lower() + if is_moderator not in ["true", "false"]: + return JsonError("Must provide is_moderator as boolean value") + is_moderator = is_moderator == "true" + user = User.objects.get(id=user_id) + role = Role.objects.get(course_id=course_id, name="Moderator") + if is_moderator: + user.roles.add(role) + else: + user.roles.remove(role) + if request.is_ajax(): + course = check_course(request.user, course_id) + discussion_user = cc.User(id=user_id, course_id=course_id) + context = { + 'course': course, + 'course_id': course_id, + 'user': request.user, + 'django_user': user, + 'discussion_user': discussion_user.to_dict(), + } + return JsonResponse({ + 'html': render_to_string('discussion/ajax_user_profile.html', context) + }) + else: + return JsonResponse({}) + @require_GET def search_similar_threads(request, course_id, commentable_id): text = request.GET.get('text', None) diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee index 79fc4a8c1f..1613cf3285 100644 --- a/lms/static/coffee/src/discussion/content.coffee +++ b/lms/static/coffee/src/discussion/content.coffee @@ -326,7 +326,7 @@ initializeFollowThread = (thread) -> handleVote($elem, "down") "click .admin-endorse": -> - handleEndorse(this, true)#, $(this).is(":checked")) + handleEndorse(this, not $content.hasClass("endorsed")) "click .discussion-openclose": -> handleOpenClose(this, $(this).text()) diff --git a/lms/static/coffee/src/discussion/main.coffee b/lms/static/coffee/src/discussion/main.coffee index ae340aba84..29d809a41b 100644 --- a/lms/static/coffee/src/discussion/main.coffee +++ b/lms/static/coffee/src/discussion/main.coffee @@ -20,4 +20,4 @@ $ -> Discussion.initializeDiscussion(discussion) Discussion.bindDiscussionEvents(discussion) - + Discussion.initializeUserProfile($(".discussion-sidebar>.user-profile")) diff --git a/lms/static/coffee/src/discussion/user_profile.coffee b/lms/static/coffee/src/discussion/user_profile.coffee new file mode 100644 index 0000000000..a431688f96 --- /dev/null +++ b/lms/static/coffee/src/discussion/user_profile.coffee @@ -0,0 +1,32 @@ +if not @Discussion? + @Discussion = {} + +Discussion = @Discussion + +@Discussion = $.extend @Discussion, + initializeUserProfile: ($userProfile) -> + $local = Discussion.generateLocal $userProfile + + handleUpdateModeratorStatus = (elem, isModerator) -> + confirmValue = confirm("Are you sure?") + if not confirmValue then return + url = Discussion.urlFor('update_moderator_status', $$profiled_user_id) + Discussion.safeAjax + $elem: $(elem) + url: url + type: "POST" + dataType: 'json' + data: + is_moderator: isModerator + error: (response, textStatus, e) -> + console.log e + success: (response, textStatus) -> + parent = $userProfile.parent() + $userProfile.replaceWith(response.html) + Discussion.initializeUserProfile parent.children(".user-profile") + + Discussion.bindLocalEvents $local, + "click .sidebar-revoke-moderator-button": (event) -> + handleUpdateModeratorStatus(this, false) + "click .sidebar-promote-moderator-button": (event) -> + handleUpdateModeratorStatus(this, true) diff --git a/lms/static/coffee/src/discussion/utils.coffee b/lms/static/coffee/src/discussion/utils.coffee index f8ee4bea83..c2ee2dcd6a 100644 --- a/lms/static/coffee/src/discussion/utils.coffee +++ b/lms/static/coffee/src/discussion/utils.coffee @@ -18,31 +18,32 @@ wmdEditors = {} urlFor: (name, param, param1) -> { - follow_discussion : "/courses/#{$$course_id}/discussion/#{param}/follow" - unfollow_discussion : "/courses/#{$$course_id}/discussion/#{param}/unfollow" - create_thread : "/courses/#{$$course_id}/discussion/#{param}/threads/create" - search_similar_threads : "/courses/#{$$course_id}/discussion/#{param}/threads/search_similar" - update_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/update" - create_comment : "/courses/#{$$course_id}/discussion/threads/#{param}/reply" - delete_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/delete" - upvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/upvote" - downvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/downvote" - undo_vote_for_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unvote" - follow_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/follow" - unfollow_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unfollow" - openclose_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/close" - update_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/update" - endorse_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/endorse" - create_sub_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/reply" - delete_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/delete" - upvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/upvote" - downvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/downvote" - undo_vote_for_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/unvote" - upload : "/courses/#{$$course_id}/discussion/upload" - search : "/courses/#{$$course_id}/discussion/forum/search" - tags_autocomplete : "/courses/#{$$course_id}/discussion/threads/tags/autocomplete" - retrieve_discussion : "/courses/#{$$course_id}/discussion/forum/#{param}/inline" - retrieve_single_thread : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}" + follow_discussion : "/courses/#{$$course_id}/discussion/#{param}/follow" + unfollow_discussion : "/courses/#{$$course_id}/discussion/#{param}/unfollow" + create_thread : "/courses/#{$$course_id}/discussion/#{param}/threads/create" + search_similar_threads : "/courses/#{$$course_id}/discussion/#{param}/threads/search_similar" + update_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/update" + create_comment : "/courses/#{$$course_id}/discussion/threads/#{param}/reply" + delete_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/delete" + upvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/upvote" + downvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/downvote" + undo_vote_for_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unvote" + follow_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/follow" + unfollow_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unfollow" + openclose_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/close" + update_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/update" + endorse_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/endorse" + create_sub_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/reply" + delete_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/delete" + upvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/upvote" + downvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/downvote" + undo_vote_for_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/unvote" + upload : "/courses/#{$$course_id}/discussion/upload" + search : "/courses/#{$$course_id}/discussion/forum/search" + tags_autocomplete : "/courses/#{$$course_id}/discussion/threads/tags/autocomplete" + retrieve_discussion : "/courses/#{$$course_id}/discussion/forum/#{param}/inline" + retrieve_single_thread : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}" + update_moderator_status : "/courses/#{$$course_id}/discussion/users/#{param}/update_moderator_status" }[name] safeAjax: (params) -> diff --git a/lms/templates/discussion/_thread.html b/lms/templates/discussion/_thread.html index 593aa1e4f4..d852d520c7 100644 --- a/lms/templates/discussion/_thread.html +++ b/lms/templates/discussion/_thread.html @@ -98,16 +98,6 @@
  • ${render_link("discussion-link discussion-reply discussion-reply-" + type, "Reply")}
  • -
  • - % if type == "comment" and request.user.is_staff: - % if content['endorsed']: - - % else: - - % endif - - % endif -
diff --git a/lms/templates/discussion/_user_profile.html b/lms/templates/discussion/_user_profile.html new file mode 100644 index 0000000000..94fe86ceaf --- /dev/null +++ b/lms/templates/discussion/_user_profile.html @@ -0,0 +1,22 @@ +<%! from django_comment_client.utils import pluralize %> +<%! from django_comment_client.permissions import has_permission, check_permissions_by_view %> + + + diff --git a/lms/templates/discussion/ajax_user_profile.html b/lms/templates/discussion/ajax_user_profile.html new file mode 100644 index 0000000000..c24081845f --- /dev/null +++ b/lms/templates/discussion/ajax_user_profile.html @@ -0,0 +1 @@ +<%include file="_user_profile.html" /> diff --git a/lms/templates/discussion/user_profile.html b/lms/templates/discussion/user_profile.html index 99d5ca5e26..87b802e66a 100644 --- a/lms/templates/discussion/user_profile.html +++ b/lms/templates/discussion/user_profile.html @@ -1,5 +1,4 @@ -<%! from django_comment_client.utils import pluralize %> -<%! from django_comment_client.permissions import has_permission, check_permissions_by_view %> +<%! from django.template.defaultfilters import escapejs %> <%inherit file="../main.html" /> <%namespace name='static' file='../static_content.html'/> @@ -20,24 +19,9 @@
+ +